POJ.2236 Wireless Network (并查集)
题意分析
查询点直接O(n)搞就行了,我想的是画个内切正方形,然后二分,或者kdtree。10sec其实不用了。
代码总览
#include <cstdio>
#include <cstring>
#include <algorithm>
#define nmax 1200
using namespace std;
struct point{
int x, y;
bool isok;
}p[nmax];
int father[nmax];
int rnk[nmax];
int n,d;
void makeset(int x){
father[x] = x;
rnk[x] = 0;
}
int findset(int x){
int r = x,temp;
while(father[r] != r) r = father[r];
while(x != r){
temp = father[x];
father[x] = r;
x = temp;
}
return r;
}
void unionset(int x, int y){
x = findset(x);
y = findset(y);
if(x == y) return;
else{
if(rnk[x] > rnk[y])
father[y] = x;
else{
father[x] = y;
if(rnk[x] == rnk[y]) rnk[x]++;
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d %d",&n,&d);
for(int i = 1;i<=n;++i) scanf("%d %d",&p[i].x,&p[i].y),makeset(i);
char op;
while(scanf(" %c",&op) != EOF){
int a,b;
if(op == 'O'){
scanf("%d",&a);
p[a].isok = true;
int temp = 0;
for(int i = 1;i<=n;++i){
if(i == a) continue;
temp = (p[i].x - p[a].x) * (p[i].x - p[a].x) + (p[i].y - p[a].y) *(p[i].y - p[a].y);
if(temp <= d * d && p[i].isok) unionset(a,i);
}
}else{
scanf("%d %d",&a,&b);
a = findset(a);
b = findset(b);
if(a == b) printf("SUCCESS\n");
else printf("FAIL\n");
}
}
return 0;
}