POJ 2236 Wireless Network

本文介绍了一个使用并查集算法解决电脑间通信问题的方法。该问题涉及到多个电脑能否直接或间接通信,并讨论了如何在修复特定电脑后更新通信状态。文章详细解释了算法实现过程,包括初始化并查集、修复电脑时的合并操作以及检查两台电脑是否能够通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目网址
题意:输入N为(坏的)电脑的数目,D是两个电脑的最大可通信距离,下面N行是N个电脑的坐标。电脑之间可以直接通信,也可以通过其他的电脑间接通信。以下有不定行输入,O后面跟着一个数字a代表修复编号为a的电脑,可以与其他的电脑通信;S后面跟着两个数字a,b,询问编号为a,b的电脑是否能通信。
所考知识点:并查集
题目解析:一开始做的时候把题想复杂了,在合并集合的时侯考虑到距离与是否修复的问题时,十分纠结。其实只要一个电脑修复,则遍历所有已修复的电脑,总能与之前的集合合并。不存在与某个根节点的距离大于给定范围,但与其父亲节点距离小于给定范围的情况无法合并的问题,因为便利了所有已修复的电脑,总能合并。

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <climits>
using namespace std;
const int MAXN=1e3+10;
int N;
double D, x[MAXN], y[MAXN];///横纵坐标储存数组
int parent[MAXN];
bool flag[MAXN];///标记电脑是否成功修复
int Find(int a)
{
    while(a!=parent[a])
        a=parent[a];
    return a;
}
bool dis(int a, int b)
{
    double c=x[a]-x[b];
    double d=y[a]-y[b];
    double e=sqrt(c*c+d*d);
    if(e<=D)
        return true;
    else
        return false;
}
void start()
{
    for(int i=0; i<=N; i++)
        parent[i]=i;
}
int main()
{
    while(cin>>N>>D)
    {
        for(int i=1; i<=N; i++)
            cin>>x[i]>>y[i];
        start();
        char x;
        int m ,n;
        while(cin>>x)
        {
            if(x=='O')
            {
                cin>>n;
                flag[n]=true;
                for(int i=1; i<=N; i++)
                {
                    if(flag[i])
                    {
                        int a=Find(i), b=Find(n);
                        if(a!=b&&dis(n,i))///遍历了所有已修复的电脑,总能与已修复的电脑集合合并
                            parent[a]=b;
                    }
                }
            }
            else if(x=='S')
            {
                cin>>m>>n;
                {
                    if(flag[m]&&flag[n]&&Find(m)==Find(n))
                        cout<<"SUCCESS"<<endl;
                    else
                        cout<<"FAIL"<<endl;
                }
            }
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值