http://acm.hdu.edu.cn/showproblem.php?pid=1232
详细介绍,很有意思:http://blog.csdn.net/dellaserss/article/details/7724401
#include <iostream> using namespace std; int parent[1050]; bool t[1050]; int find(int x) { int r = x; while(r!=parent[r]) r = parent[r]; int i = x ,j; while(parent[i]!=r) //压缩路径 { j = parent[i]; parent[i] = r; i = j; } return r; } void union_set(int x ,int y) { int fx = find(x); int fy = find(y); if(fx!=fy) { parent[fx] = fy ; } } int main() { int N,M,i,j; int a,b; int ans =0; while(scanf("%d",&N)) { if(N==0) break; scanf("%d",&M); for (i =1 ;i<=N;i++) { parent[i] = i; } for(i =1 ;i<=M;i++) { scanf("%d %d",&a,&b); union_set(a,b); //合并集合 } memset(t,0,sizeof(t)); for(i=1 ;i<=N;i++) t[find(i)] = 1; //标记根结点 ans = 0; for(i =1;i<=N;i++) if(t[i]) ans++; printf("%d\n",ans-1); } return 0; }