题目描述
机房里有若干台电脑,其中有一些电脑已经相互连接。如果A和B通过网线相连,并且B与C也通过网线相连,那么即便A和C之间没有直接的网线相连,也可以认为A和C是相连的。由于机房里的布线比较乱,并不是所有电脑都相互连通,请问在不变动当前布线情况下,最少要购买几条网线才能使得机房所有电脑都两两连通。 
输入
多组数据。每组数据第一行为整数N,M。N是电脑数量,M是机房已布置好的网线数量。接下来M行,每行为整数A,B。表明A,B之间通过一条网线直接相连。这里可以认为网线是不分方向的,即A->B等价于B->A。
(0 < N <= 200,0 <= M <= 10000,0 <= A,B <= N 。) N=0和M=0为输入结束,不需要处理。 
输出
每组一个整数,即最少还要购买几根网线。
样例输入
样例输出
提示
n个电脑编号为1~n
题解
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 
 | #include <iostream>#include <algorithm>
 using namespace std;
 #define endl '\n'
 const int maxn = 200 + 10;
 int F[maxn];
 void init(int n) {
 for (int i = 1; i <= n; i++) {
 F[i] = i;
 }
 }
 bool is_root(int x) {
 return F[x] == x;
 }
 int find(int x) {
 if (is_root(x))return x;
 return F[x] = find(F[x]);
 }
 bool merge(int x, int y) {
 int fx = find(x), fy = find(y);
 if (fx == fy)return false;
 F[fx] = fy;
 return true;
 }
 
 int count(int n) {
 int cnt = 0;
 for (int i = 1; i <= n; i++)
 if (F[i] == i)++cnt;
 return cnt;
 }
 int main() {
 ios::sync_with_stdio(false);
 cin.tie(nullptr);
 cout.tie(nullptr);
 int n, m;
 while (cin >> n >> m) {
 if (n == 0 && m == 0)break;
 init(n);
 while (m--) {
 int x, y;
 cin >> x >> y;
 merge(x, y);
 }
 cout << count(n) - 1 << endl;
 }
 return 0;
 }
 
 |