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

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

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 
 6 int n,fa[30005],num[30005];
 7 
 8 void init(){
 9     for(int i=0;i<n;i++){fa[i]=i;num[i]=1;}
10 }
11 
12 int find(int x){
13     int r=x,t;
14     while(fa[r]!=r)r=fa[r];
15     while(x!=r){
16         t=fa[x];
17         fa[x]=r;
18         x=t;
19     }
20     return r;
21 }
22 
23 int main(){
24     int m;
25     while(scanf("%d%d",&n,&m)!=EOF&&(n!=0||m!=0)){
26         init();
27         int i,j;
28         for(i=1;i<=m;i++){
29             int t,a,b;
30             cin>>t;
31             for(j=1;j<=t;j++){
32                 cin>>a;
33                 if(j==1)b=a;
34                 else{
35                     int x=find(a),y=find(b);
36                     if(x!=y){
37                         fa[x]=y;
38                         num[y]+=num[x];
39                     }
40                 }
41             }
42         }
43         int x=find(0);
44         printf("%d\n",num[x]);
45     }
46     return 0;
47 }
View Code