思路:最基础的并查集,直接写就可以,最后看看总共有几个集合,则输出总集合个数-1就是需要修的路数。
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <deque>
#include <queue>
#include <vector>
#include <algorithm>
#include <functional>
#define debug(x) cout << "--------------> " << x << endl
using namespace std;
const double PI = acos(-1.0);
const double eps = 1e-10;
const long long INF = 0x7fffffff;
const long long MOD = 1000000007;
const int MAXN = 1000 + 7;
int n, m;
int pre[MAXN];
int findRootNode(int x)
{
int r = x;
while(pre[r] != r)
r = pre[r];
int i = x;
//路径压缩
while(i != r)
{
int j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
void setMerge(int x, int y)
{
int root_x, root_y;
root_x = findRootNode(x);
root_y = findRootNode(y);
if(root_x < root_y)
pre[root_y] = root_x;
else
pre[root_x] = root_y;
}
int main()
{
while(~scanf("%d", &n))
{
if(n == 0)
break;
scanf("%d", &m);
memset(pre, 0, sizeof(pre));
for(int i = 1; i <= n; ++i)
pre[i] = i;
int city_A, city_B;
for(int i = 1; i <= m; ++i)
{
scanf("%d%d", &city_A, &city_B);
setMerge(city_A, city_B);
}
int ans = -1;
for(int i = 1; i <= n; ++i)
{
if(findRootNode(i) == i)
ans++;
}
printf("%d\n", ans);
}
return 0;
}