http://acm.hdu.edu.cn/showproblem.php?pid=3367
题意是让找出最大的森林 也就是符合它所要求的最大的边和 它要求每个连通块最多有一个圈就是一个环 可以用并查集判祖先
1 如果两个节点是一个祖先 就是一个连通块如果有圈 肯定不能合并 不然就两个圈了 就是这条边不要
2 不是一个祖先 如果是全都没圈直接合并 有一个有的合并加标记为此块有圈
View Code
1 #include <iostream> 2 #include<cstdio> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 struct node 7 { 8 int u,v,c; 9 }q[100011]; 10 int f[100001],father[10011],r[10011]; 11 int find(int x) 12 { 13 if(x!=father[x]) 14 father[x] = find(father[x]); 15 return father[x]; 16 } 17 bool cmp(node a,node b) 18 { 19 return a.c>b.c; 20 } 21 int main() 22 { 23 int i,j,k,n,m; 24 while(scanf("%d%d",&n,&m)!=EOF) 25 { 26 if(n==0&&m==0) 27 break; 28 memset(f,0,sizeof(f)); 29 int sum = 0; 30 for(i = 0; i < n; i++) 31 { 32 father[i] = i; 33 r[i] = 0; 34 } 35 for(i = 1; i <= m; i++) 36 { 37 scanf("%d%d%d",&q[i].u,&q[i].v,&q[i].c); 38 } 39 int num = 0; 40 sort(q+1,q+m+1,cmp); 41 for(i = 1; i <= m; i++) 42 { 43 int px = find(q[i].u); 44 int py = find(q[i].v); 45 if(px!=py) 46 { 47 if(!r[px]&&!r[py]||r[py]&&!r[px]||r[px]&&!r[py]) 48 { 49 if(r[py]&&!r[px]||r[px]&&!r[py]) 50 r[py] = 1; 51 father[px] = py; 52 sum+=q[i].c; 53 } 54 } 55 else 56 { 57 if(!r[px]) 58 { 59 sum+=q[i].c; 60 r[px] = 1; 61 } 62 } 63 } 64 printf("%d\n",sum); 65 } 66 return 0; 67 }