并查集模板题

这与前一个题目任意点几乎一样,只需要改一下main函数里面的一小部分代码就行
我们把联通之间的点放入一个集合,最后只需要去找根节点就知道有多少个集合,我们需要集合数减一的边就可以把这些散落的集合联系起来

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int pre[maxn];
int find(int x) //路径压缩
{
    if (x != pre[x])
        pre[x] = find(pre[x]);
    return pre[x];
}
void join(int x, int y)
{ 
    int a = find(x);
    int b = find(y);
    if (a != b)
        pre[a] = b;
}
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) //初始化
        pre[i] = i;
    for (int i = 1; i <= m; ++i)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        join(x, y);
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i)
        if (pre[i] == i)
            ++ans;
    printf("%d\n", ans - 1);
}