POJ 2236Wireless Network

来源:互联网 发布:iqr 淘宝网官网 编辑:程序博客网 时间:2024/06/01 08:29

题目网址
题意:输入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;}
原创粉丝点击