Bajtekは氷の上でスケートをすることを学んでいます。彼は初心者なので、彼の唯一の移動手段は、雪のドリフトから北、東、南、または西に押し出し、別の雪のドリフトに着陸するまで滑っています。この方法では、雪のドリフトから他の雪のドリフトに移動することは不可能であることに気づきました。彼は今、いくつかの雪の吹きだまりを積み上げて、あらゆる雪の吹きだまりから他の雪の吹きだまりに到達できるようにしたいと考えています。彼はあなたが作成する必要がある雪のドリフトの最小数を見つけるようにあなたに頼みました。
私たちは、Bajtekが整数座標でのみ雪のドリフトを積み上げることができると想定しています。
入力入力
の最初の行には、単一の整数n(1≤n≤100)、つまり雪のドリフトの数が含まれます。以下のn行のそれぞれには、2つの整数xiとyi(1≤xi、yi≤1000)が含まれています— i番目の雪のドリフトの座標。
北方向はOy軸の方向と一致するため、東方向はOx軸の方向と一致することに注意してください。すべての雪のドリフトの場所は異なります。
出力
Bajtekが他の雪のドリフトに到達できるようにするために作成する必要がある雪のドリフトの最小数を出力します。
例
入力
2
2 1
1 2
出力
1
入力
2
2 1
4 1
出力
0
質問の意味:nポイントの場合、上、下、左、右にのみ移動する必要があります。任意の2つのポイントに到達する場合は、少なくともいくつかのポイントを入力してください
アイデア:ユニオン検索セット、同じ横座標または縦座標のセットを追加し、最後にいくつかのセットを確認します。セットの数-1が答えです
ACコード:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct dian
{
int x,y;
};
int father[110];
dian g[110];
int f(int x)
{
if(father[x]==x)
return x;
else
return father[x]=f(father[x]);
}
void lian(int a,int b)
{
int l=f(a);//太久没写并查集了
int r=f(b);//这个地方一开始写错了WA了四五次
father[r]=l;
}
int main()
{
int t;
scanf("%d",&t);
for(int i=0;i<110;i++)
father[i]=i;
for(int i=0;i<t;i++)
{
scanf("%d%d",&g[i].x,&g[i].y);
for(int j=0;j<i;j++)
{
if(g[i].x==g[j].x||g[i].y==g[j].y)
{
lian(i,j);
}
}
}
int ans=0;
for(int i=0;i<t;i++)
{
if(father[i]==i)
ans++;
}
printf("%d\n",ans-1);
}