poj1611(并查集)

题目链接: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 }
原文地址:https://www.cnblogs.com/geloutingyu/p/5998548.html