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 }
浙公网安备 33010602011771号