传送门:http://poj.org/problem?id=2236
题意是有一个几个电脑需要连接起来,给出他们在直角坐标系里的坐标,每次有两种操作,可以修复一台电脑或者检测两台电脑是否可以联通。
具体实现方法主要是并查集,并查集弄这种无向图的连通性判断还是挺方便的……每次维修一台电脑之后,首先用一个re数组记下已维修电脑的编号,然后再那这个电脑和其他所有已维修的电脑循环判断,如果距离小于等于要求的距离就把两台电脑加入同一个集合。最后当有检测操作的时候,之间看根节点是否相同就行了。欢迎提问,共同交流嘛。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <math.h>
using namespace std;
const int MAXN = 1100;
int cnt = 0;
int fa[MAXN], re[MAXN];
struct Node{
int x, y;
int num;
}input[MAXN];
double dis(Node a, Node b){
double ans;
ans = sqrt( 1.0 * (a.x - b.x)*(a.x - b.x) + (a.y - b.y) * (a.y - b.y) );
return ans; //注意要用double否则会丢失精度
}
void Init(int n){
for(int i = 0;i <= n;++i)
fa[i] = i;
}
int Find(int x){
return fa[x] == x? x : fa[x] = Find(fa[x]);
}
void join(int x, int y){
int faX = Find(x), faY = Find(y);
if(faX != faY){
fa[faX] = faY;
}
}
int main()
{
//freopen("input.txt", "r", stdin);
int n, d;
scanf("%d %d", &n, &d);
Init(n);
for(int i = 0;i < n;++i){
scanf("%d %d", &input[i].x, &input[i].y);
input[i].num = i;
}
char op;
while(cin >> op){
if(op == 'O'){
int pos = 0;
scanf("%d",&pos);
re[cnt++] = --pos;
for(int i = 0;i < cnt;++i){ //将pos点与已维修数组re中的所有节点循环判断
if(dis(input[pos], input[re[i]]) <= (d * 1.0)
join(pos, re[i]);
}
}
else{
int a, b;
scanf("%d %d", &a, &b);
int faX =Find(--a), faY = Find(--b);
if(faX == faY)
printf("SUCCESS\n");
else
printf("FAIL\n");
}
}
return 0;
}