CodeForces - 218C:Ice Skating 并查集+路径压缩

题目链接:题目传送门
大意:
东东成为了快递员,现在有N个人需要送快递,由于他的车出了毛病,从平面直角坐标系上看,他只能朝上、下、左、右四个方向移动。于是他想造一些中转站,使得他可以顺利从某个人的家到达其他任意一个人的家,输出需要建造中转站的最小值。
所有人居住的坐标均为整数。
输入:
第一行包含一个整数N(1<=N<=100)表示需要送快递的人数,接下来N行,每行两个整数Xi,Yi(1<=Xi,Yi<=1000),表示第i个人居住的坐标。
输出:
需要建造的中转站的最小值,使得东东可以从任意一个人的地址到达其他任意人居住的地方。
Input1

2
2 1
1 2

Output1

1

思路:
将能够相互到达的放在一个集合,用并查集来查找,我比赛时就没写出来
代码:

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long int ll;
const ll N=1e5+10; 
int x[N],y[N],f[N];
void init()
{
 for(int i=0;i<=N;i++)
 {
  f[i]=i;
 }
}
int find(int x)
{
 if(x==f[x])
 {
  return x;
 }
 else return f[x]=find(f[x]);
}//路径压缩 
void merge(int x,int y)
{
 int a=find(x);
 int b=find(y);
 if(a!=b) 
 {
  f[a]=b;
 }
} 
int main()
{
 ios::sync_with_stdio(false);
 int n;
 cin>>n;
 init();
 for(int i=1;i<=n;i++)
 {
  cin>>x[i]>>y[i];
 }
 for(int i=1;i<=n;i++)
 {
  for(int j=1;j<=n;j++)
  {
   if(i==j)continue;
   if(x[i]==x[j]||y[i]==y[j])
   {
    merge(i,j);
   }//连接 
  }
 }
 int ans=0;
 for(int i=1;i<=n;i++)
 {
  if(f[i]==i)ans++;
 }
 cout<<ans-1;
 return 0; 
}
/**/

你可能感兴趣的:(数据结构)