题目描述
机房里有若干台电脑,其中有一些电脑已经相互连接。如果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
题解
1 2 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; }
|