并查集
#include <iostream> //并查集 poj 2524 Ubiquitous Religions
using namespace std;
int par[50010],ans[50010],n,m;
void init()
{
for(int i=1;i<=n;++i)
{
par[i]=i;
ans[i]=0;
}
}
int find_p(int i)
//路径压缩,即当我们经过"递归"找到祖先节点后,"回溯"的时候顺便将它的子孙节点都直接指向祖先,
//这样以后再次Find_Set(x)时复杂度就变成O(1)了
{
if(par[i]!=i)
{
par[i]=find_p(par[i]); //回溯时压缩路径
}
return par[i];
}
void Union(int a,int b) //合并
//每次应将小树合并到大树中,否则最坏情况下树会退化成一条链,使查找的时间复杂度为O(n)
{
int fa=find_p(a),fb=find_p(b);
if(fa==fb)
return ;
if(ans[fa]>ans[fb])
par[fb]=fa;
else
par[fa]=fb;
if(ans[fa]==ans[fb]) //若二者的高度相同,则合并后的高度要增加1
ans[fb]++;
}
int main()
{
int a,b,f,res,t=1;
while(cin>>n>>m&&n)
{
init();
res=0;
while(m--)
{
scanf("%d%d",&a,&b);
Union(a,b);
}
for(int i=1;i<=n;++i)
{
if(find_p(i)==i)
res++;
}
printf("Case %d: %d\n",t++,res);
}
return 0;
}