POJ 2236 Wireless Network

题目网址
题意:输入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;
}

猜你喜欢

转载自blog.csdn.net/qq_37495823/article/details/77073706