这道题就是说0号童鞋是有患病嫌疑的,和0号童鞋一个组的也有患病嫌疑,和有患病嫌疑在一个组的同学也有患病嫌疑,问一共有几个孩子有患病嫌疑。
首先,可以把一个组(更准确的说是被传染的)的同学放在一个集合里,然后记录下这个集合的人数,最后找到0童鞋所在的集合的人数。
#include <iostream>
#include<stdio.h>
# define max 30005
using namespace std;
int rank[max]; //秩
int num[max];//记录一个集合有多少人
int fa[max];//记录父亲结点
int find(int x){
int father=fa[x];
if(x!=fa[x])
{fa[x]=find(fa[father]);
return fa[x];}
else return father;
}
void link(int a,int b){
int x=find(a);
int y=find(b);
if(x==y) return;//如果根结点一致,说明之前已经添加过,不必重复添加
if(rank[x]>rank[y])//x的秩比y的大,把y连接到x上
{fa[y]=x;
num[x]+=num[y];}//连接后记得修改总人数
else
{if(rank[x]==rank[y])
rank[y]++;
fa[x]=y;
num[y]+=num[x];}
}
int main()
{
int n,m,i;
while(scanf("%d %d",&n,&m)!=EOF)
{
if(n+m==0)break;
for(i=0;i<n;i++){
rank[i]=1;
num[i]=1;
fa[i]=i;
}
int k,x,y;
for(i=0;i<m;i++){
scanf("%d",&k);
scanf("%d",&x);
for(int j=1;j<k;j++){
scanf("%d",&y);
link(x,y); //相邻两个进行连接
x=y;
}
}
int root=find(0);//找到0童鞋所在的根结点
int ans=num[root];
if(m==0)printf("1\n");
else printf("%d\n",ans);
}
return 0;
}