Wireless Network POJ - 2236 (并查集)

Wireless Network POJ - 2236 (并查集)_第1张图片

题解: 这道题应该是并查集的简单题目啦, 另外提醒一下大家模板这种东西最好还是要手打, 这道题目就需要对模板作一些改动
对于每台电脑我们设置一个ok的标记, 对于O操作, 我们打开标记, 并枚举把距离小于k的电脑都unite一下(我专门算了一下, 1e5+1e3刚刚好)
对于S操作, 判断isSame输出即可

#include 
#include 
#include 
#include 
#include 
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef  long long LL;
const LL maxn = 1010;

struct node{
    int x, y, par, rak;
    bool isOk; //是否被修好
}com[maxn];
int N, d;
int findr(int x){
    if(com[x].par==x) return x;
    else return com[x].par=findr(com[x].par);
}
bool isSame(int x, int y) {return findr(com[x].par)==findr(com[y].par);}
void unite(int x, int y){
    x = findr(com[x].par), y = findr(com[y].par);
    if(x == y) return;
    if(com[x].rak < com[y].rak)
        com[x].par = com[y].par;
    else{
        com[y].par = com[x].par;
        if(com[x].rak==com[y].rak) com[x].rak++;
    }
}
bool check(int x1, int y1, int x2, int y2){
    //检查是否在范围内
    return sqrt((double)(x1-x2)*(x1-x2)+(double)(y1-y2)*(y1-y2))<=d;
}
int main()
{
    scanf("%d%d",&N,&d);
    for(int i = 1; i <= N; i++){
        scanf("%d%d",&com[i].x,&com[i].y);
        com[i].par = i, com[i].rak = 0;
        com[i].isOk = false;
    }
    char opt;
    int p, q;
    while(scanf(" %c",&opt)!=EOF){
        if(opt=='O'){
            scanf("%d",&p);
            com[p].isOk = true;
            //把范围以内的所有电脑作并集处理
            for(int i = 1; i <= N; i++)
                if(i!=p && com[i].isOk && check(com[p].x, com[p].y, com[i].x, com[i].y))
                    unite(i, p);
        }
        else{
            scanf("%d%d",&p,&q);
            if(isSame(p, q)) printf("SUCCESS\n");
            else printf("FAIL\n");
        }
    }
	return 0;
}

你可能感兴趣的:(数据结构)