并查集

#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;
}

  

posted on 2011-07-17 01:32  sysu_mjc  阅读(125)  评论(0编辑  收藏  举报

导航