#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int N=50005;
int p[N],rank[N];
int Make_Set(int n)
{
int i;
for(i=0;i<=n;i++)
p[i]=i;
}
int Find_Set(int x) //路径压缩:经过"递推"找到祖先节点后,"回溯"的时候顺便将它的子孙节点都直接指向祖先
{
if(x!=p[x])
p[x]=Find_Set(p[x]);
return p[x];
}
void Union(int x,int y) //按秩合并:合并的时候将元素少的集合合并到元素多的集合中,这样合并之后树的高度会相对较小
{
x=Find_Set(x);
y=Find_Set(y);
if(x==y)
return;
if(rank[x]>rank[y])
p[y]=x;
else
{
p[x]=y;
if(rank[x]==rank[y])
rank[x]++;
}
}
int main()
{
int n,m;
int i,x,y,c=1;
while (scanf("%d %d", &n, &m) && n!=0 && m!=0)
{
for(i=1;i<=n;i++)
p[i]=i;
for (int i=1;i<=m;i++)
{
// 输入同一宗教的x和y
scanf("%d%d",&x,&y);
// 如果x和y尚未合并,将x和y进行合并,同时n--
if (Find_Set(x)!=Find_Set(y))
{
Union(x,y);
n--;
}
}
printf("Case %d: %d\n",c,n);
c++;
}
return 0;
}
POJ 2524: Ubiquitous Religions - 并查集 |裸
最新推荐文章于 2021-09-01 17:44:42 发布
最最简单和基础的并查集应用,红果果的并查集......
题意:给出n个学生,m个条件(或者说m对学生),每对学生编号分别为a,b,他们是属于一个宗教信仰的,要求输出不同宗教信仰最多有多少个。
分析详见注释。