The Suspects
Time Limit: 1000MS | Memory Limit: 20000K | |
Total Submissions: 35533 | Accepted: 17241 |
在Not-Spreading-Your-Sickness大学(
NSYSU),
有许多学生团体。同一组的学生经常彼此相通,一个学生可以同时加入几个小组。为了防止非典的传播,NSYSU收集了所有学生团体的成员名单。他们的标准操作程序(SOP)如下:
一旦一组中有一个可能的患者,
组内的所有成员就都是可能的患者。
然而,他们发现当一个学生被确认为可能的患者后不容易识别所有可能的患者。你的工作是编写一个程序,
发现所有可能的患者。
输入文件包含多组数据。
对于每组测试数据:
第一行为两个整数n和m,
其中n是学生的数量,
m是团体的数量。0 < n <=
30000,0 <= m <=
500。
每个学生编号是一个0到n-1之间的整数,一开始只有0号学生被视为可能的患者。
紧随其后的是团体的成员列表,每组一行。
每一行有一个整数k,代表成员数量。之后,有k个整数代表这个群体的学生。一行中的所有整数由至少一个空格隔开。
n = m =
0表示输入结束,不需要处理。
对于每组测试数据,
输出一行可能的患者。
100 4 2 1 2 5 10 13 11 12 14 2 0 1 2 99 2 200 2 1 5 5 1 2 3 4 5 1 0 0 0
4 1 1#include<stdio.h> int pre[40000+5]; int find(int x) { if(pre[x]==x) return x; return find(pre[x]); } void unite(int x,int y) { x = find(x); y = find(y); if(x>y) pre[x] = y; else if(x<y) pre[y]= x; } int main() { int m, n; while(~scanf("%d%d",&n,&m),m+n){ for(int i = 0;i <= n;i ++){ pre[i] = i; } while(m--){ int h, a, b; scanf("%d",&h); scanf("%d",&a); for(int i = 0;i < h-1; i++){ scanf("%d",&b); unite(a,b); } } int k = 0; for(int i = 0;i < n; i++){ if(find(i)==0) k++; } printf("%d\n",k); } return 0; }