POJ - 2236
题意:n个电脑,用Oxy坐标表示,有m次操作,如果是O x,就是将第x台电脑修复,并且其他所有好的电脑如果和它的距离小于等于d,那么就可以连通;如果是S q p,就是询问q和p是否可以连通(可以间接连通)
思路:先处理一下n台电脑相互之间的距离,如果进行O操作,那么遍历其他n-1台电脑,如果距离小于d并且电脑已被修复,那么进行集合连接;如果进行S操作,直接查询即可
#include<iostream>
using namespace std;
#define inf 0x3f3f3f3f
#define IO ios::sync_with_stdio(false)
#define bug cout << "-----\n"
typedef long long ll;
int Mod = 1000000007;
const int N = 1010;
const int M = 500010;
int dis[N][N],p[N],x[N],y[N],ok[N];
int n,d;
void Getlen() {
int i,j;
for(i=1;i<=n;i++)p[i] = i;
for(i=1;i<=n;i++) {
for(j=1;j<=n;j++) {
dis[i][j] = (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}
}
}
int find(int x) {
return x == p[x]?x:p[x] = find(p[x]);
}
void unon(int x,int y) {
int fx = find(x),fy = find(y);
if(fx!=fy)p[fx] = fy;
}
int main() {
IO;
int i,j,q,l,r;
cin >> n >> d;
d = d*d;//用距离平方比较,避免浮点数比较
for(i=1;i<=n;i++)
cin >> x[i] >> y[i];
Getlen();
char ch;
while(cin >> ch) {
if(ch=='O') {
cin >> q;
for(i=1;i<=n;i++) {
if(dis[q][i]<=d&&ok[i]) {
unon(q,i);
}
}
ok[q] = 1;
}
else {
cin >> l >> r;
int fx = find(l),fy = find(r);
if(fx==fy)cout << "SUCCESS\n";
else cout << "FAIL\n";
}
}
return 0;
}