Wireless Network POJ - 2236 并查集

题意

余震过后所有电脑都坏了,给定每一个电脑的坐标,然后给你一些操作(修复和查询),对于每一个查询输出一次这两台电脑是否能通讯

思路

在裸并查集的基础上多加个判断条件就行 ,判断每一台修复的电脑与其他电脑是否可以连接。如果该电脑被修复且与某一台已修复电脑之间的距离小于 d 则这两台电脑就可以通讯。

能通讯的条件

两台电脑都被修复且距离小于 d 。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int pre[1005],vis[1005],rank[1005];
double d;
struct node
{
    int x,y;
}p[30005];
int dis(int i,int j)
{
    double a=sqrt(1.0*(p[i].x-p[j].x)*(p[i].x-p[j].x)+1.0*(p[i].y-p[j].y)*(p[i].y-p[j].y));
    if(a>d)
        return 0;
    else
        return 1;
}
int find(int x)
{
    int r=x;
    while(r!=pre[r])
        r=pre[r];
    int i=x,j;
    while(i!=r)
    {
        j=pre[i];
        pre[i]=r;
        i=j;
    }
    return r;
}
void join(int x,int y)
{
    x=find(x),y=find(y);
    if(x!=y)
    {
        if(rank[x]>rank[y])
            pre[y]=x;
        else
        {
            pre[x]=y;
            if(rank[x]==rank[y])
                rank[y]++;
        }
    }
}
int main()
{
    int t;
    scanf("%d%lf",&t,&d);
    for(int i=1;i<=t;i++)
    {
        pre[i]=i;
        rank[i]=1;
    }
    for(int i=1;i<=t;i++)
    {
        scanf("%d%d",&p[i].x,&p[i].y);
    }
    char s;
    int n,m;
    memset(vis,0,sizeof(vis));
    getchar();
    while(~scanf("%c",&s))      //注意处理换行符
    {
        if(s=='O')
        {
            scanf("%d",&n);
            vis[n]=1;
            for(int i=1;i<=t;i++)
            {
                if(vis[i]==1&&dis(i,n))
                    join(n,i);
            }
        }
        else
        {
            scanf("%d%d",&n,&m);
            if(vis[n]==1&&vis[m]==1&&find(n)==find(m))  //只有两台电脑都被修复从才有可能通讯
                printf("SUCCESS\n");
            else
                printf("FAIL\n");
        }
        getchar();

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41837216/article/details/82953965
今日推荐