hdoj 1232 畅通工程

裸的并查集,把每个集合看成一个点,然后点的总和减1就是道路条数,比如两个点之间连通最少需要1条路;

 1 #include <stdio.h>
 2 
 3 int set[1001];
 4 
 5 int find(int n)//寻找祖先,类似双亲树
 6 {
 7     while (set[n] != n)//o(logN)
 8         n = set[n];
 9     return n;
10 }
11 
12 void merge(int a, int b)//合并集合
13 {
14     b = find(b);
15     set[b] = a;//用a的值覆盖b祖先的值,a的祖先就变成了b的祖先了
16 }
17 
18 int main()
19 {
20     int n, m;
21     while (true)
22     {
23         scanf("%d", &n);
24         if (!n)
25             break;
26         scanf("%d", &m);
27         int i, t1, t2;
28         for (i = 1; i <= n; i++)//初始化很重要,把每个数都作为自己的祖先,换句话说有n个城镇就有n个祖先(集合)
29             set[i] = i;
30         for (i = 0; i < m; i++)
31         {
32             scanf("%d %d", &t1, &t2);
33             if (find(t1) != find(t2))//判断是否为同一祖先不是的话说明不是同一集合,合并两个集合
34                 merge(t1, t2);
35         }
36         int count = -1;
37         for (i = 1; i <= n; i++)//如果下标i和对应数组值一样,set[i]就是一个集合的祖先
38             if (set[i] == i)
39                 count++;
40 
41         printf("%d\n", count);
42     }
43     return 0;
44 }

posted on 2012-08-09 19:30  Xor<>OR  阅读(125)  评论(0)    收藏  举报

导航