題目大意
學校中有很多社團,有的學生同時加了不同的社團,現在有一種病會傳染,假設一個社團裏有一個人有被傳染的嫌疑,那麼該社團的所有人都會被傳染。
初始條件: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;
}