poj1611 带权并查集

时间:2022-01-27 03:14:57

题意:病毒蔓延,现在有 n 个人,其中 0 号被认为可能感染,然后给出多个社交圈,如果某个社交圈里有人被认为可能被感染,那么所有这个社交圈里的人都被认为可能被感染,现在问有多少人可能被感染。

带权并查集,给每个集合加入这个集合的总人数,合并集合是一起合并就可以了。

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int n,fa[],num[]; void init(){
for(int i=;i<n;i++){fa[i]=i;num[i]=;}
} int find(int x){
int r=x,t;
while(fa[r]!=r)r=fa[r];
while(x!=r){
t=fa[x];
fa[x]=r;
x=t;
}
return r;
} int main(){
int m;
while(scanf("%d%d",&n,&m)!=EOF&&(n!=||m!=)){
init();
int i,j;
for(i=;i<=m;i++){
int t,a,b;
cin>>t;
for(j=;j<=t;j++){
cin>>a;
if(j==)b=a;
else{
int x=find(a),y=find(b);
if(x!=y){
fa[x]=y;
num[y]+=num[x];
}
}
}
}
int x=find();
printf("%d\n",num[x]);
}
return ;
}