牛客練習賽16 C 任意點【並查集/DFS/建圖模型】

連接:https://www.nowcoder.com/acm/contest/84/C
來源:牛客網

題目描述 
平面上有若干個點,從每一個點出發,你能夠往東南西北任意方向走,直到碰到另外一個點,而後才能夠改變方向。
請問至少須要加多少個點,使得點對之間互相能夠到達。
輸入描述:
第一行一個整數n表示點數( 1 <= n <= 100)。
第二行n行,每行兩個整數xi, yi表示座標( 1 <= xi, yi <= 1000)。
y軸正方向爲北,x軸正方形爲東。
輸出描述:
輸出一個整數表示最少須要加的點的數目。
示例1
輸入
2
2 1
1 2
輸出
1
示例2
輸入
2
2 1
4 1
輸出
0

【分析】:ios

若兩個點橫座標或者縱座標相同,兩點間連一條邊,經過dfs統計連通塊的個數。spa

固然並查集也是能夠的,但因爲不涉及給出任意兩個點判斷是否連通,所以dfs更輕便。code

【出處】: CodeForces 217A Ice Skatingci

【代碼】:get

/*
將行相同或列相同的點合併爲一棵樹,最後看有多少棵樹便可計算還需多少個點。
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int father[1001];

int find(int x)
{
    if(father[x]==x)
       return x;
    else
       {
           father[x]=find(father[x]);
           return  father[x];
       }
}

void merge(int a,int b)
{
    int fa=find(a);
    int fb=find(b);
    if(fa!=fb)
    {
      father[fb]=fa;
    }
}

int main()
{
    int n;
    while(cin>>n&&n)
    {
        int x[n+1],y[n+1],ans=0;

        for(int i=1;i<=n;i++)
            father[i]=i;
        for(int i=1;i<=n;i++)
        {
            cin>>x[i]>>y[i];
        }

        for(int i=1;i<n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
               if(x[i]==x[j]||y[i]==y[j])
                {
                    merge(i,j);
                }
            }
        }

        for(int i=1;i<=n;i++)
        {
           if(father[i]==i)
               ans++;
        }
        cout<<ans-1<<endl;
    }
     return 0;
}
相關文章
相關標籤/搜索