4 2 1 3 4 3 3 3 1 2 1 3 2 3 5 2 1 2 3 5 999 0 0
1 0 2 998====并查集的处子秀。。。。#include<iostream> #include<cstdio> using namespace std; int n,m; int rank[1005],r[1005]; void init() { for(int i=1;i<=n;i++) { r[i]=i; //初始化根。 rank[i]=1; //初始化树高。 } } int root(int a) //找根。 { if(r[a]==a) return a; else return r[a]=root(r[a]); } void merge(int a,int b) //合并两个集合。 { int ra,rb; ra=root(a); rb=root(b); if(ra==rb) return; if(rank[ra]==rank[rb]) //两树高相等时,树高加1。 r[rb]=ra,rank[ra]++; else if(rank[ra]>rank[rb]) r[rb]=ra; else if(rank[ra]<rank[rb]) r[ra]=rb; } int main() { int i,x,y; while(~scanf("%d",&n),n) { scanf("%d",&m); init(); for(i=1;i<=m;i++) { scanf("%d%d",&x,&y); merge(x,y); } int count=0; for(i=1;i<=n;i++) { if(r[i]==i) count++; } cout<<count-1<<endl; } return 0; }
原文:http://blog.csdn.net/darwin_/article/details/22077799