poj1611(并查集)

时间:2021-12-23 13:18:12

题目链接:http://poj.org/problem?id=1611

题意:

SARS(非典型肺炎)传播得非常厉害,其中最有效的办法是隔离那些患病、和患病者接触的人。现在有几个学习小组,每小组有几个学生,一个学生可能会参加多个小组。小组中只要有一个人得病,其余的都是嫌疑人。现在已知这些小组的人员,且已知0号学生是患病嫌疑人,求一共有多少个嫌疑人。

思路:用并查集按组合并,然后遍历一遍,0号学生祖先相同则计数加一;

注意:此题数据比较大,要压缩路径,不然会超时;

代码:

 #include <iostream>
#include <stdio.h>
#define MAXN 30000+10
using namespace std; int pre[MAXN]; int find(int x){
int r=x;
while(x!=pre[x]){
x=pre[x];
}
int i=r;
while(x!=i){
int gg=pre[i];
pre[i]=x;
i=gg;
}
return x;
} void jion(int x, int y){
int xx=find(x);
int yy=find(y);
if(xx!=yy){
pre[xx]=yy;
}
} int main(void){
int n, m;
while(scanf("%d%d", &n, &m)&&(n||m)){
for(int i=; i<n; i++){
pre[i]=i;
}
while(m--){
int k, gg, x;
scanf("%d%d", &k, &x);
for(int i=; i<k; i++){
scanf("%d", &gg);
jion(x, gg);
}
}
int ans=;
for(int i=; i<n; i++){
if(find(i)==find()){
ans++;
}
}
printf("%d\n", ans);
}
return ;
}