The Suspects

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

View Code
 1 #include<stdio.h>
 2 int father[30001], num[30001] ;
 3 int i ;
 4 void Init(int n)
 5 {
 6     for(i=0; i<n; i++)
 7     {
 8         father[i] = i ;
 9         num[i] = 1 ;
10     }
11 }
12 int find(int x)
13 {
14     if(father[x]!=x)
15     father[x] = find(father[x]) ;
16     return father[x] ;
17 }
18 int Union(int x, int y)
19 {
20     int fx, fy ;
21     fx = find(x) ;
22     fy = find(y) ;
23     if(fx==fy)
24     return 0 ;
25     if(num[fx]<=num[fy])
26     {
27         father[fx] = fy ;
28         num[fy] += num[fx] ;
29     }
30     else
31     {
32         father[fy] = fx ;
33         num[fx] +=num[fy] ;
34     }
35     return 0 ;
36 }
37 int main()
38 {
39     int n, m, j ;
40     while(scanf("%d%d",&n,&m)!=EOF&&n!=0)
41     {
42         Init(n) ;
43         for(i=0; i<m; i++)
44         {
45            int a, b, c ;
46            scanf("%d %d", &a, &b) ;
47            for(j=1; j<a; j++ )
48            {
49                scanf("%d", &c) ;
50                Union(b, c) ;
51            }
52         }
53         printf("%d\n", num[find(0)]) ;
54     }
55     return 0 ;
56 }

典型的并查集,最初各自为集,然后每个group进行合并,等到所有的group合并完,题目也就解决了,因为在合并的时候,如果哪两个group中有重合的元素,则那个后来的group会由于按秩合并的原则自动合并到
先有的集合当中.

原文地址:https://www.cnblogs.com/yelan/p/2921145.html