件名の説明:
アイススケート
テストあたりの時間制限
2秒
テストごとのメモリ制限
256メガバイト
入力
標準入力
出力
標準出力
Bajtekは氷の上でスケートを学んでいます。彼は交通の彼の唯一のモードは、北、東、南または西に雪ドリフトから押し出すと、彼は別の雪のドリフトに着地するまでスライドさせ、初心者です。彼はこのようにそれが動くの任意の順序でいくつかの他に、いくつかの雪のドリフトから取得することは不可能だということに気づきました。彼は今、彼は他のものに任意のスノードリフトから得ることができるように、いくつかの追加の雪のドリフトを盛り上げたいと考えています。彼は、作成する必要が雪のドリフトの最小数を見つけるためにあなたを尋ねました。
私たちは、Bajtekのみ整数座標で雪のドリフトを盛り上げできることを想定しています。
入力
入力の最初の行は、単一の整数含まN(1≤ N 雪ドリフトの数- 100≤)を。以下の各n個のラインは2つの整数を含ま* X ** iは*と* Y ** iは*(1≤ X I 、 Y Iが 1000以下) -の座標I番目の雪ドリフト。
注意の方向と北方向coinсidesその線Oyの軸のでの方向と東方向coinсides 牛軸。すべての雪ドリフトの位置が異なっています。
出力
出力Bajtekが他のものから任意の雪のドリフトに到達できるようにするために作成する必要が雪のドリフトの最小数。
例
入力
コピー
2
2 1
1 2
出力
コピー
1
入力
コピー
2
2 1
4 1
出力
コピー
0
アイデア:
唯一の同じx座標やyがこれらの点は、現在のすべての接続のニーズに加えていくつかのポイントを尋ねることができるようにするために、相互に接続するために同じの座標に、いくつかの点で、これらのポイントを言って題さ。これは良いポイントの数、どのように私はこれらの点は、それらの点のそれぞれと通信することはできません知っている、プラスのポイントであり、任意の場所に増加することをので、その質問には、最初は、トラブルのビットを感じるかもしれません。しかし、実際には任意の場所にプラスの点を考慮していない、私たちはライン上で通信のポイントが何であるかに焦点を当てる必要があります。図は、通信側を構築し、次いで図の強連結成分の数であることができ、これらの点を構築しました。各ポイント内の強連結成分が強連結成分であり、nは、我々が一緒に強連結成分入れ、強連結成分を形成するために、これらの点を接続し、達成されます。N-1ライン上のエッジを構築する方法にも限り。このn-1個のエッジが実際にドットの改造に対応します。しかし、私は、書く本に別のアルゴリズムをコピーする方法をtarjan忘れてしまったが、それは、テンプレート、右にtarjanの書き込みを見て少し問題です。
コード:
#include <iostream>
#include <stack>
#include <vector>
#define max_n 1005
using namespace std;
typedef pair<int,int> PII;
vector<PII> vec;
int head[max_n];
int cnt = 0;
struct edge
{
int v;
int nxt;
}e[max_n<<1];
void add(int u,int v)
{
++cnt;
e[cnt].v = v;
e[cnt].nxt = head[u];
head[u] = cnt;
}
int n,m;
int idx = 0;
int Bcnt;
int instack[max_n];
int dfn[max_n];
int low[max_n];
int belong[max_n];
stack<int> s;
void tarjan(int u)
{
dfn[u] = low[u] = ++idx;
s.push(u);
instack[u]=1;
int v;
for(int i = head[u];i;i=e[i].nxt)
{
v = e[i].v;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u],low[v]);
}
else if(instack[v])
{
low[u] = min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u])
{
Bcnt++;
do
{
v=s.top();
s.pop();
instack[v]=0;
belong[v]=Bcnt;
}while(u!=v);
}
}
int main()
{
cin >> n;
for(int i = 0;i<n;i++)
{
int x,y;
cin >> x >> y;
vec.push_back(PII(x,y));
}
for(int i = 0;i<n;i++)
{
for(int j = i+1;j<n;j++)
{
if(vec[i].first==vec[j].first||vec[i].second==vec[j].second)
{
add(i,j);
add(j,i);
}
}
}
for(int i = 0;i<n;i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
cout << Bcnt-1 << endl;
return 0;
}