这道题看似有点像数学的题目,但实际上是并查集的应用,输入的结点从1编号到n,然后初始化并查集set[i]=i,然后双重循环判断任意两点是否是一个集合的,如果两个点有x或者y相等,则两点属于一个集合。最后看有多少个集合,得到的数字减1 就是结果。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
typedef struct Node
{
int x;
int y;
}node;
node a[110];
int set[110];
bool vis[110];
int findSet(int x)//查找元素x所属集合
{
if(x==set[x])
return x;
else
return set[x]=findSet(set[x]);
}
void unionSet(int x,int y)//x和y合并到一个集合中
{
int fx=findSet(x);
int fy=findSet(y);
set[fy]=fx;
}
int main()
{
int n;
scanf("%d",&n);
int i,j;
for(i=1;i<=110;i++)
set[i]=i;
for(i=1;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
for(i=1;i<=n-1;i++)
{
for(j=1;j<=n;j++)
{
if(i==j) continue;
if(a[i].x==a[j].x || a[i].y==a[j].y)
{unionSet(i,j);}
}
}
int s=0;
for(i=1;i<=n;i++)
if(set[i]==i) s++;//统计有多少个集合
printf("%d",s-1);
//system("pause");
return 0;
}