UVa 10600 - ACM Contest and Blackout
2014-03-22 15:34
393 查看
题目:计算一个图的最小生成树和次小生成树。
分析:图论,最小生成树。冤家题(⊙_⊙),2011年北京赛区现场赛A题类似物。
当时在赛场上想到了kruskal+bfs的加边删边算法。由于写错了一行代码最后悲剧了。
利用kruskal算法先计算出最小生成树,然后设置maxe[i][j]数组,
记录i到j在最小生成树上的路径中的最长边,这个计算利用bfs是O(|V|)的(|E|=|V|-1)
然后遍历所有的边如果不是smt上的边,就加进去,减掉这个环上的其它边中最长的,即maxe
更新判断,取出最小值即为次小生成树。T = O(|V|*|V|+|E|)=O(|V|*|V|)
方法2,利用prim算法,计算maxe的过程和节点更新过程相似,可同时进行,处理简单。T =(|V|*|V|)
方法3,遍历每条边,然后扫描所有不在smt上的边,求解,找到最小即可,可能TLE。T = O(|E|*|V|)
注意:(⊙_⊙)都是眼泪( ⊙ o ⊙ )啊!
分析:图论,最小生成树。冤家题(⊙_⊙),2011年北京赛区现场赛A题类似物。
当时在赛场上想到了kruskal+bfs的加边删边算法。由于写错了一行代码最后悲剧了。
利用kruskal算法先计算出最小生成树,然后设置maxe[i][j]数组,
记录i到j在最小生成树上的路径中的最长边,这个计算利用bfs是O(|V|)的(|E|=|V|-1)
然后遍历所有的边如果不是smt上的边,就加进去,减掉这个环上的其它边中最长的,即maxe
更新判断,取出最小值即为次小生成树。T = O(|V|*|V|+|E|)=O(|V|*|V|)
方法2,利用prim算法,计算maxe的过程和节点更新过程相似,可同时进行,处理简单。T =(|V|*|V|)
方法3,遍历每条边,然后扫描所有不在smt上的边,求解,找到最小即可,可能TLE。T = O(|E|*|V|)
注意:(⊙_⊙)都是眼泪( ⊙ o ⊙ )啊!
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> using namespace std; typedef struct d_node { int point1; int point2; int weight; }enode; enode edge[5005]; int ismt[5005]; //link typedef struct l_node { int point; int weight; l_node *next; }lnode; lnode *l_head[101]; lnode l_node[20002]; int l_count; void link_inital() { l_count = 0; memset( l_head, 0, sizeof(l_head) ); } void link_add( int a, int b, int c ) { l_node[l_count].point = b; l_node[l_count].weight = c; l_node[l_count].next = l_head[a]; l_head[a] = &l_node[l_count ++]; } //end_link //union_set int sets[101]; int rank[101]; void set_inital( int a, int b ) { for ( int i = a ; i <= b ; ++ i ) { rank[i] = 0; sets[i] = i; } } int set_find( int a ) { if ( a != sets[a] ) sets[a] = set_find( sets[a] ); return sets[a]; } void set_union( int a, int b ) { if ( rank[a] < rank[b] ) sets[a] = b; else { if ( rank[a] == rank[b] ) rank[a] ++; sets[b] = a; } } //end_union_set int cmp_e( enode a, enode b ) { return a.weight < b.weight; } int kruskal( int n, int m ) { memset( ismt, 0, sizeof(ismt) ); sort( edge, edge+m, cmp_e ); set_inital( 1, n ); int sum = 0; for ( int i = 0 ; i < m ; ++ i ) { int A = set_find( edge[i].point1 ); int B = set_find( edge[i].point2 ); if ( A != B ) { set_union( A, B ); ismt[i] = 1; sum += edge[i].weight; } } return sum; } int maxe[101][101]; int smap[101][101]; int used[101]; int queue[101]; void bfs( int s ) { memset( used, 0, sizeof(used) ); used[s] = 1; queue[0] = s; for ( int move = 0,save = 1 ; move < save ; ++ move ) { int now = queue[move]; for ( lnode* p = l_head[now] ; p ; p = p->next ) if ( !used[p->point] ) { used[p->point] = 1; maxe[s][p->point] = max( maxe[s][now], p->weight ); queue[save ++] = p->point; } } } int main() { int t,n,m,a,b,c; while ( scanf("%d",&t) != EOF ) while ( t -- ) { scanf("%d%d",&n,&m); link_inital(); for ( int i = 0 ; i < m ; ++ i ) { scanf("%d%d%d",&a,&b,&c); edge[i].point1 = a; edge[i].point2 = b; edge[i].weight = c; } int k = kruskal( n, m ); for ( int i = 0 ; i < m ; ++ i ) if ( ismt[i] ) { link_add( edge[i].point1, edge[i].point2, edge[i].weight ); link_add( edge[i].point2, edge[i].point1, edge[i].weight ); } memset( maxe, 0, sizeof(maxe) ); for ( int i = 1 ; i <= n ; ++ i ) bfs( i ); int Max = 300003,p1,p2; for ( int i = 0 ; i < m ; ++ i ) { p1 = edge[i].point1; p2 = edge[i].point2; if ( !ismt[i] && Max > k+edge[i].weight-maxe[p1][p2] ) Max = k+edge[i].weight-maxe[p1][p2]; } printf("%d %d\n",k,Max); } return 0; }
相关文章推荐
- kuangbin专题八 UVA 10600 ACM Contest and Blackout(次小生成树)
- UVA 10600 ACM Contest and Blackout 次小生成树
- ACM Contest and Blackout - UVA 10600 - 次小生成树
- UVA 10600 ACM Contest and Blackout(次小树,3级)
- UVA 10600 ACM Contest and Blackout
- UVA 10600 ACM Contest and Blackout(次小树,3级)
- UVA10600-ACM Contest and Blackout
- UVa 10600 - ACM Contest and Blackout(最小生成树)
- ACM Contest and Blackout UVA - 10600
- UVa 10600 ACM contest and Blackout( 次小生成树)
- UVA 10600 ACM contest and Blackout(次小生成树)
- UVa:10600 ACM Contest and Blackout
- Uva 10600 ACM Contest and Blackout(次小生成树)
- UVA 10600 ACM Contest and Blackout(最小生成树and次小生成树)
- uva 10600 ACM Contest and Blackout(次小生成树)
- uva 10600 ACM Contest and Blackout
- UVA 10600 - ACM Contest and Blackout(最小生成树&次小生成树)
- UVA 10600 - ACM Contest and Blackout(次小生成树)
- UVA 10600 - ACM Contest and Blackout 次小生成树
- (beginer) 最小生成树 UVA 10600 ACM Contest and Blackout