hdu 1856 More is better
简单的并查集,用到了路径压缩
题意:找出节点数最多的连通分支,并输出该节点数。
思路:统计每个连通分支的节点数(利用并查集构建图时进行路径压缩,用一个与根节点下标对应的sum数组记录节点数),比较后得出最大值。
1 #include<cstdio> 2 #include<cstring> 3 4 int set[10000000 + 50]; 5 int sum[10000000 + 50]; 6 bool visit[10000000 + 50]; 7 8 int find(int x) 9 { 10 int r = x; 11 while(set[r] != r) 12 r = set[r]; 13 int i = x; 14 int j; 15 while(i != r) 16 { 17 j = set[i]; 18 set[i] = r; 19 i = j; 20 } 21 return r; 22 } 23 24 void merge(int a, int b) 25 { 26 int i = find(a); 27 int j = find(b); 28 if(i != j) set[i] = j; 29 visit[a] = visit[b] = true; 30 return ; 31 } 32 33 int main() 34 { 35 int a,b,n; 36 while(~scanf("%d",&n)) 37 { 38 if(n == 0) 39 { 40 printf("1\n"); 41 continue; 42 } 43 for(int i = 1; i <= 10000000; i++) 44 set[i] = i; 45 for(int i = 0; i < n; i++) 46 { 47 scanf("%d%d",&a,&b); 48 merge(a,b); 49 } 50 for(int i = 1; i <= 10000000; i++) 51 { 52 if(visit[i]) 53 { 54 sum[find(i)]++; 55 } 56 } 57 int max = 0; 58 for(int i = 1; i <= 10000000; i++) 59 { 60 if(visit[i] && set[i] == i) 61 { 62 if(sum[i] > max) 63 max = sum[i]; 64 } 65 } 66 printf("%d\n",max); 67 memset(visit,0,sizeof(visit)); 68 memset(sum,0,sizeof(sum)); 69 } 70 return 0; 71 }