poj 1611(并查集)

http://poj.org/problem?id=1611

题意:有个学生感染病毒了,只要是和这个学生接触过的人都会感染,而和这些被感染者接触的人,也会被感染,现在给定你一些协会的人数,以及所在学生的编号,要你求被感染的人数。

思路:首先,把同一个社团的人,合并到一个这个社团的第一个人的那里,并用一个数组记录这个集合有多少人,最后查找0这个元素在哪个集合就可以。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define l 30005
 4 
 5 int belg[l],num[l];
 6 
 7 int Find(int x)
 8 {
 9     int _x=x,_b;
10     while(_x!=belg[_x])
11     {
12         _x=belg[_x];
13     }
14     while(x!=belg[x])
15     {
16         _b=belg[x];
17         belg[x]=_x;
18         x=_b;
19     }
20     return _x;
21 }
22 
23 void unio (int x,int y)
24 {
25     int root1=Find(x);
26     int root2=Find(y);
27     if(root1!=root2)
28     {
29         belg[root1]=root2;
30         num[root2]+=num[root1];    //合并的时候,记得把人数也合并。
31     }
32 }
33 
34 int main()
35 {
36     int m,n,a,b,c;
37   //  freopen("in.txt","r",stdin);
38     while(scanf("%d%d",&m,&n))
39     {
40         if(m==n&&m==0) break;
41         if(m==0) printf("1
");
42         for(int i=0;i<m;i++)
43         {
44             belg[i]=i;
45             num[i]=1;
46         }
47         for(int i=0;i<n;i++)
48         {
49             scanf("%d%d",&a,&b);
50             for(int i=1;i<a;i++)
51             {
52                 scanf("%d",&c);
53                 unio(b,c);
54                 b=c;
55             }
56         }
57         printf("%d
",num[Find(0)]);
58     }
59     return 0;
60 }
原文地址:https://www.cnblogs.com/Tree-dream/p/5711876.html