题目链接:http://poj.org/problem?id=1611
题意:
SARS(非典型肺炎)传播得非常厉害,其中最有效的办法是隔离那些患病、和患病者接触的人。现在有几个学习小组,每小组有几个学生,一个学生可能会参加多个小组。小组中只要有一个人得病,其余的都是嫌疑人。现在已知这些小组的人员,且已知0号学生是患病嫌疑人,求一共有多少个嫌疑人。
思路:用并查集按组合并,然后遍历一遍,0号学生祖先相同则计数加一;
注意:此题数据比较大,要压缩路径,不然会超时;
代码:
1 #include <iostream>
2 #include <stdio.h>
3 #define MAXN 30000+10
4 using namespace std;
5
6 int pre[MAXN];
7
8 int find(int x){
9 int r=x;
10 while(x!=pre[x]){
11 x=pre[x];
12 }
13 int i=r;
14 while(x!=i){
15 int gg=pre[i];
16 pre[i]=x;
17 i=gg;
18 }
19 return x;
20 }
21
22 void jion(int x, int y){
23 int xx=find(x);
24 int yy=find(y);
25 if(xx!=yy){
26 pre[xx]=yy;
27 }
28 }
29
30 int main(void){
31 int n, m;
32 while(scanf("%d%d", &n, &m)&&(n||m)){
33 for(int i=0; i<n; i++){
34 pre[i]=i;
35 }
36 while(m--){
37 int k, gg, x;
38 scanf("%d%d", &k, &x);
39 for(int i=1; i<k; i++){
40 scanf("%d", &gg);
41 jion(x, gg);
42 }
43 }
44 int ans=0;
45 for(int i=0; i<n; i++){
46 if(find(i)==find(0)){
47 ans++;
48 }
49 }
50 printf("%d
", ans);
51 }
52 return 0;
53 }