题意
平面上有若干个点,从每个点出发,你可以往东南西北任意方向走,直到碰到另一个点,然后才可以改变方向。
请问至少需要加多少个点,使得点对之间互相可以到达。
题解
如果n个点之间可以相互到达,则将n个点放入一个集合。所需添加的点数就是集合数-1
故:可以遍历所有点对,若彼此可达,则使用并查集将二者并到一起。
最后查询祖先为自身的点数,即树根数集合数。
Code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int fa[maxn]; //记录祖先节点
vector<pair<int,int>> a ;
int fi(int x){ //find函数寻找祖先
return x == fa[x] ? x : fa[x] = fi(fa[x]);
}
void un(int x,int y){ //union函数建立两点关系
int p = fi(x);
int q = fi(y);
if(p != q) fa[p] = q;
}
int main()
{
int n,m;
cin>>n;
a.resize(n);
for(int i = 1;i <= n;++i) fa[i] = i; //init
for(int i = 1;i <= n;++i){
scanf("%d%d",&a[i].first,&a[i].second);
}
for(int i = 1;i <= n;++i){
for(int j = i + 1;j <= n;++j){
if(a[i].first == a[j].first || a[i].second == a[j].second){
un(i,j);
}
}
}
int cnt =0 ;
for(int i = 1;i <= n;++i){
if(fa[i] == i){
cnt++;
}
}
printf("%d\n",cnt-1);
return 0;
} 
京公网安备 11010502036488号