一个并查集的裸体
对于两个点在什么情况下可以联通:
横坐标相同或者纵坐标相同(在同一行或者同一列)
然后求图中有几个联通块就可以了,假如有n个联通块,我需要加n-1个点能够使他们全部联通使得任两点之间可以互相到达
代码
#include <map> #include <set> #include <cmath> #include <stack> #include <queue> #include <cstdio> #include <bitset> #include <vector> #include <iomanip> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #include <unordered_map> #define UpMing main #define re register #pragma GCC optimize(2) #define Accept return 0; #define lowbit(x) ((x)&(-(x))) #define mst(x, a) memset( x,a,sizeof(x) ) #define rep(i,a,b) for(int i=(a);i<=(b);++i) #define dep(i,a,b) for(int i=(a);i>=(b);--i) using namespace std; typedef long long ll; typedef pair<int,int> PII; typedef unsigned long long ull; const int inf =0x3f3f3f3f; const int maxn=5e5+7; const ll mod = 1e9+7; const int N =1e6+3; inline ll read() { ll x=0; bool f=0; char ch=getchar(); while (ch<'0'||'9'<ch) f|=ch=='-', ch=getchar(); while ('0'<=ch && ch<='9') x=x*10+ch-'0',ch=getchar(); return f?-x:x; } void out(ll x) { int stackk[20]; if(x<0) { putchar('-'); x=-x; } if(!x) { putchar('0'); return; } int top=0; while(x) stackk[++top]=x%10,x/=10; while(top) putchar(stackk[top--]+'0'); } ll n,p[maxn],ans; ll find(ll x) { if(p[x]==x) return x; return p[x]=find(p[x]); } void combine(ll x,ll y) { ll dx=find(x); ll dy=find(y); if(dx!=dy) p[dx]=dy; } struct wmy { ll x,y,id; } a[121]; int UpMing() { n=read(); for(int i=1 ; i<=n ; i++) p[i]=i; for(int i=1 ; i<=n ; i++) { a[i].x=read(); a[i].y=read(); a[i].id=i; } for(int i=1 ; i<n ; i++) { for(int j=i+1 ; j<=n ; j++) { if(a[i].x==a[j].x||a[i].y==a[j].y) combine(i,j); } } for(int i=1 ;i<=n ;i++) if(p[i]==i) ans++; out(ans-1); Accept; }