题目链接
题目大意
有一种传染病,在同一社团的学生有可能被传染,有(0 < n < = 30000)个学生,和(0 < =m < = 500)个社团,其中0号学生被怀疑感染,找出有多少学生可能被感染此类传染病。
分析
此题运用到并查集,将同一社团的学生进行合并,将与0号学生祖先相等的学生进行计数
代码
#include <stdio.h>
int f[30010];
int getf(int x)//查找祖先
{
return x==f[x] ? x : f[x]=getf(f[x]);
}
void h(int x,int y)//合并
{
x=getf(x);
y=getf(y);
if(x == y)
return ;
f[y]=x;
}
int main()
{
int n,m;
int i,j;
while(scanf("%d%d",&n,&m),n)//n=0,m=0结束
{
for(i=0;i<n;i++)//初始化
f[i]=i;
int s,s0,s1;
for(i=1;i<=m;i++)
{
scanf("%d",&s);
scanf("%d",&s0);//输入社团的第一个人,其他人与他合并
for(j=1;j<s;j++)
{
scanf("%d",&s1);
h(s0,s1);
}
}
int q,count=1;
q=getf(0);//0号学生祖先
for(i=1;i<n;i++)
{
if(q == getf(i))//祖先相等,计数
count++;
}
printf("%d\n",count);
}
return 0;
}