并查集_无线网络

时间限制: 5 Sec  内存限制: 128 MB
提交: 471  解决: 115
[提交][状态][讨论版]

题目描述

一场地震在东南亚发生了。不幸的是ACM组织通过电脑建立的无线网络遭到了毁灭性的影响—--网络中所有的电脑都损坏了。在陆续的维修电脑之后,无线网络有逐渐开始再一次运作了。由于硬件的制约,每两台电脑只能保持不超过d米的距离,才可以直接进行通讯。但是每台电脑又可以作为其它两台电脑通讯的中介点,也就是说假设A电脑与B电脑不在能直接通讯的的范围内,但是它们可以通过同时能与A和B电脑通讯的C电脑建立间接通讯关系。
在维修的过程中,维修者可以进行两种操作:维修一台电脑或者检测两台电脑之间是否能够通讯。你的任务就是解答每一次的检测操作。

输入

第一行包含两个整数N和d (1 <= N <= 1001, 0 <= d <= 20000).N表示电脑的数量,电脑编号从1开始到N,d为两台能直接通讯的电脑所需保持的距离的最大值。在接下来的N行里,每行包含两个整数xi, yi (0 <= xi, yi <= 10000),表示N台电脑的坐标。接下来的一系列的输入都表示维修者的操作,每种操作都是以下两种中的一种:
1. "O p" (1 <= p <= N),表示维修第p台电脑。
2. "S p q" (1 <= p, q <= N), 表示检测p与q电脑是否能够通讯。
输入不会超过300000 行。 

输出

对于每组检测操作,若两台电脑能进行通讯就输出"SUCCESS",否则输出"FAIL"。

样例输入

4 1
0 1
0 2
0 3
0 4
O 1
O 2
O 4
S 1 4
O 3
S 1 4

样例输出

FAIL
SUCCESS

并查集思想,不过有个细节,就是p和q可能相同,即使没有维修也是可以直接通讯的。一时的疏忽,导致WA了好几发……

#include<bits/stdc++.h>
using namespace std;
char s[2];
int vis[1005],fa[1005];
struct node
{
    int x,y;
}a[1005];
int root(int x)
{
    while(x!=fa[x]) x=fa[x];
    return x;
}
void mer(int p,int q)
{
    int pp=root(p);
    int qq=root(q);
    if(pp!=qq) fa[pp]=qq;
}
int main()
{
    int n,p,q,d;
    scanf("%d%d",&n,&d);
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y),fa[i]=i;
    while(scanf("%s",s)==1)
    {
        if(s[0]=='O')
        {
            scanf("%d",&p);
            vis[p]=1;
            for(int i=1;i<=n;i++)
            {
                if(vis[i])
                {
                    int ans=(a[i].x-a[p].x)*(a[i].x-a[p].x)+(a[i].y-a[p].y)*(a[i].y-a[p].y);
                    if(ans<=d*d)
                        mer(p,i);
                }
            }
        }
        else
        {
            scanf("%d%d",&p,&q);
            int qq=root(q);
            int pp=root(p);
            if(pp==qq) printf("SUCCESS\n");//vis[p]&&vis[q]&&pp==qq这样写会WA
            else printf("FAIL\n");
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41061455/article/details/81395848
今日推荐