题意:有若干组,每组都为n个人中的若干人;病毒在同一组内的人之间会互相传播;0号人患病,问需要隔离多少人
思路:并查集;
方案1:同一组内的人合并,最后查找有多少个和0号人同组。
方案2:另外开一个sum数组,存放当前组内的总共人数。最后统计0号人所在组的总共人数。注意sum只对组内的根节点有意义。
方案1:
#include <stdio.h>
#include <string.h>
#define N 30005
int father[N];
int n,m;
int find(int x){
if(father[x] == x)
return x;
else return father[x] = find(father[x]);
}
void merge(int x,int y){
int xx = find(x);
int yy = find(y);
father[xx] = yy;
}
int main(){
freopen("a.txt","r",stdin);
while(scanf("%d %d",&n,&m) && (n||m)){
int i,x,y,num,res=0,index;
for(i = 0;i<n;i++)
father[i] = i;
while(m--){
scanf("%d",&num);
for(i = 0;i<num;i++)
if(!i)
scanf("%d",&x);
else{
scanf("%d",&y);
merge(x,y);
}
}
index = find(0);
for(i = 1;i<n;i++)
if(find(i) == index)
res++;
printf("%d\n",res+1);
}
return 0;
}
方案2:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 30005
int fa[N],sum[N];
int n,m;
int find(int x){
if(fa[x] == x)
return x;
return fa[x] = find(fa[x]);
}
void merge(int x,int y){
int xx = find(x);
int yy = find(y);
if(xx != yy){
fa[xx] = yy;
sum[yy]+=sum[xx];
}
}
int main(){
while(scanf("%d %d",&n,&m) && (n+m)){
int i,num,a,b;
for(i = 0;i<n;i++){
fa[i] = i;
sum[i] = 1;
}
while(m--){
scanf("%d",&num);
scanf("%d",&a);
for(i = 1;i<num;i++){
scanf("%d",&b);
merge(a,b);
}
}
printf("%d\n",sum[find(0)]);
}
return 0;
}