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