[http://acm.hnust.cn/JudgeOnline/problem.php?cid=1310&pid=0]
分析:若简单的用数组,难免会消耗很大的内存空间,而且通过排序,可能会TLE,而并查集的时间复杂度接近O(1),因此用并查集。两个学生信仰同一个宗教就合并(即把他们的父节点置为同一个)
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=50005;
int par[N];
int Find(int x)///找根结点
{
int r=x;
while(par[r]!=r)
r=par[r];
int t=x;
while(t!=r)
{
int m=par[t];
par[t]=r;
t=m;
}
return r;
}
/*int Find(int x)
{
return par[x]==x?x:Find(par[x]);
}*/
void unite(int x,int y)//合并
{
x=Find(x);
y=Find(y);
if(x!=y)
par[x]=y;
}
int main()
{
int n,k=0,m;
while(~scanf("%d%d",&n,&m))
{
if(!m&&!n) break;
int p,q,num=0;
for(int i=1;i<=n;i++)
par[i]=i;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&p,&q);
unite(p,q);
}
for(int i=1;i<=n;i++)
if(par[i]==i)
num++;
printf("Case %d: %d\n",++k,num);
}
return 0;
}