Wireless Network (并查集) POJ - 2236

An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have set up a wireless network with the lap computers, but an unexpected aftershock attacked, all computers in the network were all broken. The computers are repaired one by one, and the network gradually began to work again. Because of the hardware restricts, each computer can only directly communicate with the computers that are not farther than d meters from it. But every computer can be regarded as the intermediary of the communication between two other computers, that is to say computer A and computer B can communicate if computer A and computer B can communicate directly or there is a computer C that can communicate with both A and B.

In the process of repairing the network, workers can take two kinds of operations at every moment, repairing a computer, or testing if two computers can communicate. Your job is to answer all the testing operations.


 

Input

The first line contains two integers N and d (1 <= N <= 1001, 0 <= d <= 20000). Here N is the number of computers, which are numbered from 1 to N, and D is the maximum distance two computers can communicate directly. In the next N lines, each contains two integers xi, yi (0 <= xi, yi <= 10000), which is the coordinate of N computers. From the (N+1)-th line to the end of input, there are operations, which are carried out one by one. Each line contains an operation in one of following two formats:
1. "O p" (1 <= p <= N), which means repairing computer p.
2. "S p q" (1 <= p, q <= N), which means testing whether computer p and q can communicate.

The input will not exceed 300000 lines.


 

Output

For each Testing operation, print "SUCCESS" if the two computers can communicate, or "FAIL" if not


Sample Input
4 1
0 1
0 2
0 3
0 4
O 1
O 2
O 4
S 1 4
O 3
S 1 4

Sample Output
FAIL
SUCCESS


题意:南亚发生了一次地震。亚洲联合医疗队已经电脑搭建了一个无线网络,但受到了一次不可预知的余震攻击,因此网络中的所有电脑都被破坏了。
电脑被逐台修复,网络逐步恢复了工作。由于受到硬件的约束,每台电脑只能与距离它不超过 d 米的其它电脑直接通信。
但每台电脑可被看作其它两台电脑的通信中转点,也就是说,如果电脑 A 和电脑 B 可以直接通信,或存在一台电脑 C 既可与 A 也可与 B 通信,
那么电脑 A 和电脑 B 之间就能够通信。
在处理网络修复的过程中,工作人员们在任何一个时刻,可以执行两种操作:维修一台电脑,或测试两台电脑是否能够通信。请您找出全部的测试操作。
第一行包含了两个整数 N 和 d (1 <= N <= 1001, 0 <= d <= 20000)。此处 N 是电脑的数目,编号从 1 到 N;
同时,D 是两台电脑之间能够直接通信的最大距离。
接下来的 N 行,
每行包含两个整数 xi, yi (0 <= xi, yi <= 10000),表示 N 台电脑的坐标。从第 (N+1) 行到输入结束,是逐一执行的操作,每行包含一个操作,格式是以下两者之一:
1. "O p" (1 <= p <= N),表示维护电脑 p 。
2. "S p q" (1 <= p, q <= N),表示测试电脑 p 和 q 是否能够通信。
输入不超过 300000 行。

思路:并查集,每修好一台电脑,就遍历所有修好的电脑,如果在通讯范围内,就把他们并在一个集合里。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include <sstream>
#include<vector>
#include<cmath>    
#include<stack>
#include<time.h>
#include<ctime>
using namespace std;
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL long long
#define maxn 100000005    
int pre[100009] = {};
int rootsearch(int root)
{
    int son;
    son = root;
    while (root != pre[root])//这个数不是领导,继续往下找
    {
        root = pre[root];
    }
    while (son != root)//路径压缩,把找到的下级数全部指向最高领导
    {
        int temp = pre[son];
        pre[son] = root;
        son = temp;
    }
    return root;//返回最高领导
}
struct node
{
    int x;
    int y;
}s[100009];
int vis[100009] = {};
int main()
{
    int N, D, a, b;
    char flag;
    scanf("%d%d", &N, &D);
    for (int i = 1; i <= N; i++)//记录N个点的坐标
    {
        scanf("%d%d", &s[i].x, &s[i].y);
    }
    for (int i = 1; i <= N; i++)//开一个数组
    {
        pre[i] = i;
    }
    while (~scanf("\n%c", &flag))//读入条件
    {
        if (flag == 'S')
        {
            scanf("%d%d", &a, &b);
            if (rootsearch(a) == rootsearch(b))//在同一个集合里
            {
                printf("SUCCESS\n");
            }
            else
            {
                printf("FAIL\n");
            }
        }
        else
        {
            scanf("%d", &a);
            pre[a] = a;
            vis[a] = 1;//标记已经修好了
            for (int i = 1; i <= N; i++)
            {
                if (vis[i] && i != a)//遍历已经修好的电脑
                {
                    if (rootsearch(i) != rootsearch(a))//不在同一集合
                    {
                        if ((s[i].x - s[a].x) * (s[i].x - s[a].x) + (s[i].y - s[a].y) * (s[i].y - s[a].y) <= D * D)//在通讯范围之内
                        {
                            pre[rootsearch(i)] = rootsearch(a);//合并
                        }
                    }
                }
            }
        }
    }
}

 

posted @ 2020-06-09 22:08  夜灯长明  阅读(141)  评论(0编辑  收藏  举报