您的位置:首页 > 其它

POJ 2524 (并查集)

2016-04-03 21:15 453 查看
题目大意:

已知一个学校有不同的种族,给定n个人,和m对人,每对人他们的信仰一样,问n个人有多少种信仰?前提是每个人只有一个信仰

思路:如果a和b信仰相同,那么他们就属于同一集合。如果a和c相同,那么就把c加入到该集合中,很明显,属于同一集合里面的人信仰相同,那么问题就变成了求这n个人共有多少个集合。 首先,将n个人初始化为n个集合,发现a和b之间信仰相同并且它们之间不构成环的话,集合数减1,最后的集合数就是问题的答案。 这里为什么要强调不构成环,因为考虑1,2,3点,开始集合数为3,1和2之间信仰相同,集合数减1;2和3之间信仰相同,集合数减1;此时,若2和3之间信仰相同,因为2和3构成了环,所以这里集合数不需要减。
其实,构成了环,就表明从已知条件可以推出2和3信仰相同,题目给的条件是多余的信息而已。

#include <iostream>
using namespace std;

#define MAX 50010

int p[MAX];
int ans; //保存集合的数量,每个集合代表一个种族

int Find(int a){
return a==p[a]?a:Find(p[a]);
}

void Union(int u,int v){
int x = Find(u);
int y = Find(v);
if(x!=y){
ans--;
p[x] = y;
}
}

int main(){
int n,m,i;
int a,b;
int num = 0;
while(cin>>n>>m){
num++;
for(i=0;i<n;i++){
p[i] = i;
}
ans = n; //初始化每个点代表一个集合
if(n==0&&m==0) break;
for(i=0;i<m;i++){
cin>>a>>b;
Union(a,b);
}
cout<<"Case "<<num<<": "<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: