Union lookup Wireless Network

Posted by abbe-rocks on Thu, 21 Nov 2019 21:56:52 +0100

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

emmmmmm, it took half an hour to write the code, and an hour to change the bug. Finally, it was found that FAIL was reached, so it's time to call

We have n computers that are not repaired. Each time, we give the coordinates of each computer,
Each computer can only communicate with repaired computers within a distance of d,
Computer communication can only be between two computers, and can be expanded through a third computer.
Perform a series of operations on these computers. Operation 'O' p stands for repairing the P computer,
To operate 'S' p q means to ask whether the computer p and Q can communicate with each other

Idea: for a typical look-up and union set, for each computer repaired, we traverse all computers (of course, we can also store the repaired computers in an array), and judge whether the two computers can be combined into a set each time. If so, we will merge.
The judgment condition is that the root nodes are different and meet the requirements, that is, the distance d is not exceeded and it has been repaired

Code:

#include<string.h>
#include<iostream>
using namespace std;

int n,d;
int p,q;
char state;
int pro[1010];//Used to record the parent node
int cnt[1010];//For storage depth
struct node
{
    double x;
    double y;
    int open;//Indicates whether the computer has been repaired
}arr[1010];

void init()//Initialization function
{
    for(int i = 1 ; i <= n ; i++)
    {
        pro[i] = i;//At the beginning, every computer was its own root
        cnt[i] = 0;
    }
}

int myfind(int root)//Find root function
{
    if(pro[root] == root)
        return root;
    else
        return pro[root] = myfind(pro[root]);
}

bool judge(int x,int y)//Judgement function
{
    if(arr[x].open && arr[y].open &&(((arr[x].x - arr[y].x) * (arr[x].x - arr[y].x) + (arr[x].y - arr[y].y) * (arr[x].y - arr[y].y)) <= d * d))
        return true;
    else
        return false;
}
void myjoin(int x,int y)//Merging function
{
    int root1 = myfind(x);
    int root2 = myfind(y);
    
    if(root1 == root2)//If the root nodes of the two points are the same, there is no need to merge
        return;
        
    else if(cnt[root1] < cnt[root2])//If it's not the same, add the one with the smaller depth to the one with the deeper depth
        pro[root1] = root2;
        
    else
    {
        pro[root2] = root1;
        if(cnt[root1] == cnt[root2])//If it's equal, the depth will be + 1
            cnt[root1] += 1;
    }
}

int main(void)
{
    cin >> n >>d;
    
    init();//Initialization
    
    for(int i = 1 ; i <= n ; i++)
    {
        cin >> arr[i].x >> arr[i].y;
        arr[i].open = 0;
    }
    
    while(cin >> state)
    {
        if(state == 'O')
        {
            cin >> p;
            arr[p].open = 1;
            for(int i = 1 ; i <= n ; i++)
            {
                if(i != p && judge(i,p))
                    myjoin(i,p);
            }
        }
        else if(state == 'S')
        {
            cin >> p >> q;
            if(myfind(p) == myfind(q))
                cout << "SUCCESS" << endl;
            else
                cout << "FAIL" << endl;
        }
    }
}

Topics: network