题目大意:给出N个点,刚开始每个点都是坏的,每个点都有相互连接,但是要满足两点之间的距离小于dis才可以进行通信
现在给出2种操作
O i:修复第i台电脑
S u v:询问第u台和第v台电脑能否通信
解题思路:用并查集将所有能通信的电脑并在一起,如果新修了电脑,那就找寻一下他所能连接的集合,然后并进去
因为该电脑可能起着连接多个集合的作用,所以集合也要相应合并
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 1010
int x[maxn], y[maxn], com[maxn][maxn], f[maxn], r[maxn];
int n, d;
int find(int t) {
return t == f[t] ? t : f[t] = find(f[t]);
}
bool judge(int i, int j) {
return (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]) <= d * d;
}
int main() {
int tmp[maxn], vis[maxn];
scanf("%d%d", &n, &d);
for(int i = 1; i <= n; i++)
scanf("%d%d", &x[i], &y[i]);
for(int i = 1; i <= n; i++) {
f[i] = i;
r[i] = 0;
for(int j = i + 1; j <= n; j++) {
if(judge(i,j))
com[i][j] = com[j][i] = 1;
else
com[i][j] = com[j][i] = 0;
}
}
char op[10];
int xx, yy;
while(scanf("%s", op) != EOF) {
if(op[0] == 'O') {
scanf("%d", &xx);
int i, cnt = 0;
for(int i = 1; i <= n; i++)
vis[i] = 0;
for(i = 1; i <= n; i++)
if(r[i] && i != xx && com[i][xx]) {
int fi = find(i);
if(!vis[fi]) {
tmp[cnt++] = fi;
vis[fi] = 1;
}
}
if(cnt == 0) {
r[xx] = 1;
}
else {
int fa = tmp[0];
for(int i = 1; i < cnt; i++)
f[tmp[i]] = fa;
f[xx] = fa;
r[xx] = 1;
}
}
else {
scanf("%d%d", &xx, &yy);
int fxx = find(xx);
int fyy = find(yy);
if(fxx == fyy)
printf("SUCCESS\n");
else
printf("FAIL\n");
}
}
return 0;
}