poj 2236 Wireless Network 并查集

本文介绍了一个使用并查集算法解决电脑联络问题的方法。该问题涉及通过判断距离来确定电脑之间是否能够互相联络,并根据修复指令实时更新联络状态。文章提供了完整的代码实现,并解释了如何利用并查集维护联络关系。

题目大意:有n台电脑,并给出每台电脑的坐标,给出距离d意为距离小于等于d的电脑之间才可以联系,且如果A-B,B-C可联系,则A-C也可以联系。输入一系列命令 O代表修复某天电脑,S代表查询某两台电脑是否可以联系。

题目思路:利用并查集将能联系的电脑划分到一个集合内,如果两点的根节点相同则可以联系,属于比较简单的并查集吧。

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
#define MAX 1000005

using namespace std;

int father[MAX],x[MAX],y[MAX],v[MAX];

double Dist(int a,int b)//计算两点间距离
{
    double k1=(x[a]-x[b])*(x[a]-x[b])*1.0;
    double k2=(y[a]-y[b])*(y[a]-y[b])*1.0;

    return sqrt(k1+k2);
}

int Find(int x)
{
    while(father[x]!=x)
    {
        x=father[x];
    }

    return x;
}

int main()
{
    int n,i,j,k,a,b,X,Y;
    char op[5];//为了避免不必要的麻烦用“%s”读入命令
    double dist,d;

    while(scanf("%d%lf",&n,&d)!=EOF)
    {
        memset(v,0,sizeof(v));

        for(i=1;i<=n;i++)
            father[i]=i;

        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&x[i],&y[i]);
        }

        while(scanf("%s",&op)!=EOF)
        {
            if(op[0]=='O')//更新
            {
                scanf("%d",&k);
                v[k]=1;

                for(i=1;i<=n;i++)
                {
                    if(v[i])
                    {
                        dist=Dist(k,i);

                        if(dist <= d)
                        {
                            X=Find(k);
                            Y=Find(i);

                            if(X!=Y)
                            {
                                father[X]=Y;
                            }
                        }
                    }
                }
            }

            else
            {
                scanf("%d%d",&a,&b);

                if(!v[a] || !v[b])//如果存在未修复的点则失败
                {
                    printf("FAIL\n");
                    continue;
                }

                X=Find(a);
                Y=Find(b);

                if(X!=Y)
                {
                    printf("FAIL\n");
                }

                else
                {
                    printf("SUCCESS\n");
                }
            }
        }
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/alan-W/p/5746197.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值