题意给你n个人,编号从0到n-1,再给你m个组,接下来的m行分别输入该组有多少人,且分别为编号为多少.0号是病毒感染者,与0号直接或间接在一起的都有可能感染该病毒,要求你输出可能感染病毒的人数(包括0号).
思路:并查集思想,因为0号是感染源,所以我们再输入组数人员编号时,统一把大的号数往小的上面并,则每组人员都链接起来了,则我们直接遍历一下pre数组中有多少个0就可以了.(因为最小为0号,跟他有关系的pre中最终都是0号)
代码如下:
#include<cstdio>
const int maxn=30007;
int n,m,pre[maxn];
int Find(int x){
if(x==pre[x]) return x;
return Find(pre[x]);
}
void Union(int x,int y){//与通常的有点不一样的写法.
int m=Find(x);
int n=Find(y);
if(n<m){
pre[m]=n;
}
if(n>m){
pre[n]=m;
}
}
void ini()
{
for(int i=0;i<n;i++){
pre[i]=i;
}
}
int main()
{ int k,a,b;
while(scanf("%d %d",&n,&m)!=EOF && n!=0 || m!=0){
ini();
for(int i=0;i<m;i++){
scanf("%d",&k);
scanf("%d",&a);
for(int j=1;j<k;j++){
scanf("%d",&b);
Union(a,b);
}
}
int ans=0;
for(int i=0;i<n;i++){
if(!Find(i))
ans++;
}
printf("%d\n",ans);
}
}