题目大意
学校中有很多社团,有的学生同时加了不同的社团,现在有一种病会传染,假设一个社团里有一个人有被传染的嫌疑,那么该社团的所有人都会被传染。
初始条件:0号学生有嫌疑,算出所有有嫌疑的学生总数。
题解
将每组输入的学生编号使用并查集联系起来,然后找出0号元素的祖先,输出个数。此处用一个辅助sum数组来统计属于本节点的元素个数,所以最后输出sum[find(id[0])]即为所求。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
const int M = 30005;
int id[M];
int sum[M];
int find(int p)
{
while(p != id[p]) p = id[p];
return p;
}
//bool connected(int p,int q)
//{
// return find(p) == find(q);
//}
void unionn(int p,int q)
{
int pRoot = find(p);
int qRoot = find(q);
if(pRoot != qRoot)
{
id[qRoot] = pRoot; //q->p
sum[pRoot] += sum[qRoot];
}
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m))
{
// int count = 0;
/*if(m == 0)
{
printf("1\n");
continue;
}*/
if(n == 0 && m == 0)
break;
for(int i = 0;i < n; i++) //初始化
{
id[i] = i;
sum[i] = 1;
}
for(int i = 0;i < m;i++)
{
int t;
int p,q;
scanf("%d",&t);
scanf("%d",&p);
for(int j = 1;j < t;j++)
{
scanf("%d",&q);
unionn(p,q); //依次相连,从后往前
p = q;
}
}
/*for(int i = 0; i < n;i++)
{
if(find(i) == id[0])
++count;
}*/
int x = find(id[0]);
printf("%d\n",sum[x]);
}
return 0;
}