B - Wireless Network POJ - 2236 Simple and understandable union search (path compression, merge by rank)

The meaning of the question : In a plane, there are n computers, but all the computers are broken at this time, give the coordinates (x, y) of each computer and a distance d

If the computers are good, and the distance between the computers is less than d, then the two computers can be connected, and the computers can be connected with the help of the computer, that is, if
a--b b--c then a--c can be considered. Now give two operations, 'O' means to repair a computer, 'S' means to check whether the two computers are connected

If yes, output "SUCCESS" otherwise output "FAIL"

Idea : It is an obvious question of union search. If the distance between two computers is less than d, they are considered to be directly connected. If both computers are repaired and connected, they are considered to be connected. Two computers merged collection. The query can directly determine whether the two computers are in a set.
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
int n,D;
int par[1005],rk[1005],link[1005][1005],vis[1005]//link records the contact, whether the vis record is repaired;
int X[1005], Y[1005];//Record the coordinates
void init()//initialization
{
    for(int i=1;i<=n;i++){
        par [i] = i;
        rk[i]=0;
    }
}
int Find(int x)//Find (preferably written as a non-recursive search method)
{
    while(x!=par[x])
       x=by[x];
    return x;
}
void unite(int x,int y)//merge
{
    x=Find(x);
    y=Find(y);
    if(x==y)
        return ;
    if(rk[x]<rk[y])
        by[x]=y;
    else{
        by[y]=x;
        if(rk[x]==rk[y])
            rk[x]++;
    }
}
bool same(int x,int y)//Determine whether it is in a set
{
    return Find(x)==Find(y);
}
intmain()
{
    memset(link,0,sizeof link);
    memset(vis,0,sizeof vis);
    scanf("%d%d",&n,&D);
    init();
    for(int i=1;i<=n;i++)
        scanf("%d%d",&X[i],&Y[i]);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++){
        if((X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j])<=D*D){//建立联系
            link[i][j]=1;
        }
    }
    char ch[2];
    int a,b;
    while(~scanf("%s",ch)){
        if(ch[0]=='O'){//After repairing a computer, judge whether this computer can communicate with other computers
            scanf("%d",&a);
            force[a]=1;
            for(int i=1;i<=n;i++)
                if(vis[i]==true&&i!=a&&link[a][i])
                    unite(a,i) ;
            }
        else if(ch[0]=='S'){
            scanf("%d%d",&a,&b);
            if(same(a,b))
                printf("SUCCESS\n");
            else
                printf("FAIL\n");
        }
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326521130&siteId=291194637