题解:
跟加边的无向图其实差不多,就是看看添加几条边让其图中的边都可以相互到达,因为用的是路径压缩的算法,所以我们只需要查看一下一空有几个集合,也就是说有几个f[x]==x(根节点)就可以了。

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

int ifind(int x){
    if(f[x]==x) return  x;
    else return f[x]=ifind(f[x]);
}
struct wazxy{
    int x,y;
}a[maxn];
int main(){
    int n;
    cin>>n;
    for(int i=0;i<maxn;i++) f[i]=i;
    for(int i=0;i<n;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
    }
    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            if(a[i].x==a[j].x||a[i].y==a[j].y){
                int dx=ifind(i+1);
                int dy=ifind(j+1);
                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;
}