题目大意:第一行给你n个大学生 m种关系 接下来m行为一个大学生与另一个大学生存在相同信仰,让你估算这n个学生中最多有多少种宗教信仰。(每个学生最多信仰一个宗教。 )
解题思路:基本就是并查集的模板 没什么大的变化 首先先初始化标记数组p所以得大学生喜欢不同的宗教。 对给出的每对大学生 x,y 如果他们在不同的集合,就合并他们,然后宗教数减1。还有注意此题最好用scanf输入
下面就上代码了。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <vector>
using namespace std;
#define FOR(i,m) for(int i=0;i<m;i++)
#define sc(n,m) scanf("%d %d",&n,&m)
int n,m,ans;
int p[50005];
void init()//初始化每个大学生的信仰
{
for(int i=0;i<=n;i++)
{
p[i]=i;
}
}
int Find(int x)
{
if(x!=p[x])
{
p[x]=Find(p[x]);//注意状态压缩 不压缩可能会超时
}
return p[x];
}
void UnionSet(int x,int y)//合并函数
{
int xx=Find(x);
int yy=Find(y);
if(xx!=yy)//判断是否在同一个集合内
{
p[yy]=xx;
ans--;
}
}
int main()
{
int num=1;
while(~sc(n,m))
{
if(n==0&&m==0)
break;
init();
ans=n;
FOR(i,m)
{
int x,y;
sc(x,y);
UnionSet(x,y);
}
printf("Case %d: %d\n",num++,ans);
}
return 0;
}
END!!!!!!!!!!!!!!!!!!!!!!