题解:
并查集路径压缩的方法就可以很简单得做出来这个题目,因为所有孩子都直接连向他的父节点,所以我们判断一共有多少个关系得时候可以直接统计一下共有几个父节点即可也就是,f[i]==i;
代码:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 1e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;
int n,m;
int f[maxn];
int ifind(int x){
    if(x==f[x]) return x;
    return f[x]=ifind(f[x]);
}

int main(){
    cin>>n>>m;
    for(int i=0;i<maxn;i++) f[i]=i;
    while (m--){
        int x,y;
        scanf("%d%d",&x,&y);
        int dx=ifind(x);
        int dy=ifind(y);
        if(dx!=dy){
            f[dx]=dy;
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        if(f[i]==i) ans++;
    }
    cout<<ans-1<<endl;
    return 0;
}