Wireless Network 题解(并查集应用)

Time limit Memory limit OS
10000 ms 65536 kB
Linux

A - Wireless Network

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

题目考察基本的并查集,关键是理解题意,题目说的是给出一些坏电脑的坐标,再给出任意个操作(可以用!=EOF),操作为修复一台电脑,或者判断两台电脑是否可以联网。刚开始没理解题意,走了很多弯路。关键是O后面那个数字到底代表啥,为何可以用一个数来代表表示一台电脑,或者代表一个坐标,或者代表两个数。其实O后面这个数字是代表输入电脑坐标时的编号,就是把坏电脑编号为1,2,3,,,,n。这样就可以用这个编号,来确定一个集合中各台电脑的联系。

具体看代码:

#include<cstdio>
#include<cstring>
using namespace std;
int f[1005],dis[1005][2];
bool v[1005];   //是否已修复的标记
int getf(int x) //查找根节点
{
    if(f[x]==x) return x;
    return f[x]=getf(f[x]);
}
void unite(int a,int b) //合并
{
    f[b]=a;
}

int main() {
    int n,d;
    memset(v,0, sizeof(v));   //初始化
    scanf("%d %d",&n,&d);
    for(int i=1;i<=n;i++)
    {
        scanf("%d %d",&dis[i][0],&dis[i][1]);   //把电脑编号,欠存储坐标值
        f[i]=i;
    }
    int a,b,fa,fb;
    char s[2];
    while(scanf("%s",&s)!=EOF)    //不建议用%c,那样会带来各种各样的问题,相反用%s不容易出错
    {
        if(s[0]=='O')
        {
            scanf("%d",&a);
            if(v[a]) continue;    //如果已经修复就不在向下执行,因为在其他循环中也会遍历到它
            v[a]=1;
            for(int i=1;i<=n;++i)  //遍历所有电脑,把可能联网的电脑放入同一个集合中
            {
                fa=getf(i);fb=getf(a);
                if(v[i]&&((dis[i][0]-dis[a][0])*(dis[i][0]-dis[a][0])+(dis[i][1]-dis[a][1])*(dis[i][1]-dis[a][1]))<=d*d)//判断电脑之间的距离和是否已经被修复
                {
                    if(fa!=fb)  unite(fa,fb);
                }
            }

        }
       else
        {
            scanf("%d%d",&a,&b);
            if(getf(a)==getf(b))
                printf("SUCCESS\n");
            else
                printf("FAIL\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43301061/article/details/86574258