天天看點

HDU-2236-Wireless Network(并查集)

Wireless Network

Time Limit: 10000MS Memory Limit: 65536K

Total Submissions: 24404 Accepted: 10167

Description

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

Source

題意:首行給出N和D,代表有N個點,接着N行給出N個點的坐标,接着開頭是O代表激活某點,開頭是S,代表詢問兩點之間是否聯通。初始任意點都沒有聯通,對于任意兩點都被需要激活,且兩點間距離小于等于D,兩點才能聯通。

維護一個并查集即可

代碼

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
const int maxn=;
const int INF=;
int Father[maxn];//并查集數組
struct node
{
    int x;
    int y;
};
node num_1[maxn];//N個點的坐标
int num_2[maxn];//存儲已激活的點
int flag[maxn];//标記i點是否被激活
int num;//已激活點的數量
int N,D;
int Find_father(int x)//查找到x的爹
{
    if(x!=Father[x])
        Father[x]=Find_father(Father[x]);
    return Father[x];
}
bool Judge(node x,node y)
{
    double dis=sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
    if(dis>D)
        return false;
    return true;
}
int main()
{
    scanf("%d%d",&N,&D);
    for(int i=; i<=N; i++)
    {
        flag[i]=;//标記i點未被激活
        Father[i]=i;//i的爹是自己
    }
    for(int i=; i<=N; i++)
        scanf("%d%d",&num_1[i].x,&num_1[i].y);
    num=;
    char str[];
    while(scanf("%s",str)!=EOF)
    {
        if(str[]=='O')
        {
            int point;
            scanf("%d",&point);
            if(flag[point]==)//如果point沒被激活過
            {
                flag[point]=;
                for(int i=; i<num; i++) //周遊point和之前激活過的點
                {
                    if(Judge(num_1[num_2[i]],num_1[point]))//兩點距離合法
                    {
                        int flag_x=Find_father(num_2[i]);
                        int flag_y=Find_father(point);
                        if(flag_x!=flag_y)
                            Father[flag_x]=flag_y;
                    }
                }
                num_2[num++]=point;
            }
        }
        else if(str[]=='S')
        {
            int x,y;
            scanf("%d%d",&x,&y);
            if(Find_father(x)==Find_father(y))
                printf("SUCCESS\n");
            else
                printf("FAIL\n");
        }
    }
    return ;
}