HDU1232 畅通工程 (并查集)

题目:

  中文的就不说了~~~~

思路:

  属于并查集的基础题,比较典型,可以把连通在一起的看成是一个点,假设一共有N个独立的点,那么就需要 N - 1 条边把他们连通起来,所以利用并查集算法,最后统计有多少个独立的集合,然后把这个数减去一便是我们所要的答案了~~~~

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cmath>
 6 #include <cctype>
 7 #include <algorithm>
 8 using namespace std;
 9 const int MAXN = 1e3 + 3;
10 int pre[MAXN]; //保存的是父节点的值
11 bool root[MAXN];  //是否为根节点
12 
13 int Find(int x)
14 {
15     int r = x;
16     while(pre[r] != r)
17     {
18         r = pre[r];
19     }
20     int i = x,j;
21     while(pre[i] != r)
22     {
23         j = i;
24         i = pre[i];
25         pre[j] = r;
26     }
27     return r;
28 }
29 
30 void mix(int a,int b)
31 {
32     int x = Find(a);
33     int y = Find(b);
34     if(x > y)
35     {
36         pre[x] = y;
37     }
38     if(x < y)
39     {
40         pre[y] = x;
41     }
42 }
43 
44 int main()
45 {
46     int M,N;
47     while(~scanf("%d",&M)&&M)
48     {
49         scanf("%d",&N);
50         for(int i = 1; i <= M; i++)
51         {
52             pre[i] = i;
53             root[i] = false;
54         }
55         while(N--)
56         {
57             int a,b;
58             scanf("%d%d",&a,&b);
59             mix(a,b);
60         }
61         for(int i = 1; i <= M; i++)
62         {
63             if(pre[i] == i)
64                 root[i] = true;
65         }
66         int ans = 0;
67         for(int i = 1; i <= M; i++)
68         {
69             if(root[i]) ans ++;
70         }
71         printf("%d
",ans-1);
72     }
73     return 0;
74 }
It's not numeral,character and punctuation .It's my life.
原文地址:https://www.cnblogs.com/Ash-ly/p/5397658.html