Niu Ke Practice Match 16 C Any Point [Union Check/DFS/Mapping Model]

链接: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

【analyze】:

If the abscissa or ordinate of two points is the same, an edge is connected between the two points, and the number of connected blocks is counted by dfs.

Of course, union search is also possible, but since it does not involve giving any two points to determine whether they are connected, dfs is more portable.

【Source】:
CodeForces 217A Ice Skating

【Code】:

/*
将行相同或列相同的点合并为一棵树,最后看有多少棵树即可计算还需多少个点。
*/
#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;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325062563&siteId=291194637