题目大意:ACM公司,有n台电脑损坏了,现在可以进行两种操作,O表示修复一台电脑,S表示查询这两台电脑之间是否可以相连通,相连通的条件有两个,满足一个即可,一、这两台电脑之间距离小于等于d,二、这两台电脑可以通过其他电脑相互达到。
分析:用并查集维护可以联通的电脑,当修好一台电脑后,遍历一遍已修好的电脑,如果距离小于等于d,就加入并查集中。这样查询的时候,只要判断两台电脑是否在一个并查集即可。
代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
struct dot{
int x, y;
};
dot a[1111];
int n, f[1111];
double d;
int repaired[1111];
int Find(int k) {
return f[k] == k ? k : f[k] = Find(f[k]);
}
void Union(int i, int j) {
int pi = Find(i);
int pj = Find(j);
if(pi == pj) return ;
else f[pi] = pj;
}
bool dist(int i, int j) {
double dd = sqrt(1.0*(a[i].x-a[j].x)*(a[i].x-a[j].x)+1.0*(a[i].y-a[j].y)*(a[i].y-a[j].y));
if(dd <= d ) return true;
else return false;
}
int main() {
scanf("%d%lf", &n, &d);
for(int i = 1; i <= n; i++) {
scanf("%d%d", &a[i].x, &a[i].y);
f[i] = i;
}
char op[2];
int p, q, cnt = 0;
memset(repaired, 0, sizeof(repaired));
while(scanf("%s%d", &op, &p) != EOF) {
if(op[0] == 'O') {
for(int i = 0; i < cnt; i++) { //与已修好的电脑合并
if(dist(repaired[i], p))
Union(repaired[i], p);
}
repaired[cnt++] = p;
}
else {
scanf("%d", &q);
if(Find(p) == Find(q)) printf("SUCCESS\n");
else printf("FAIL\n");
}
}
return 0;
}