http://poj.org/problem?id=2236
给定n台电脑,两台计算机的最大通信距离d,以及这些电脑的坐标。
然后有两种操作,O表示该台电脑修好;S,表示测试这两台电脑能不能进行正常的通信
简单并查集。
每修好一台电脑就对其它已经修好的电脑遍历,如果距离≤d,就将他们合并。之后判断2台电脑是不是一个集合中。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=1005;
int n,d;
int fa[maxn];
int rank[maxn];
bool use[maxn];
bool ok[maxn][maxn];
void init(){
for (int i=1;i<=n;i++){
fa[i]=i;
rank[i]=0;
}
}
int find(int x){
if (x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
void unite(int x,int y){
x=find(x);
y=find(y);
if (x==y) return;
if (rank[x]<rank[y]){
fa[x]=y;
}
else{
fa[y]=x;
if (rank[x]==rank[y]){
rank[x]++;
}
}
}
bool same(int x,int y){
return find(x)==find(y);
}
pair <int,int> com[maxn];
int main(){
cin >> n >> d;
for (int i=1;i<=n;i++){
cin >> com[i].first >> com[i].second;
}
init();
for (int i=1;i<=n;i++){
for (int j=i;j<=n;j++){
if ((com[i].first-com[j].first)*(com[i].first-com[j].first)+(com[i].second-com[j].second)*(com[i].second-com[j].second)<=d*d){
ok[i][j]=ok[j][i]=true;
}
}
}
char ch;
while (cin >> ch){
if (ch=='O'){
int x;
cin >> x;
use[x]=true;
for (int i=1;i<=n;i++){
if (i!=x&&use[i]&&ok[x][i]){
unite(x,i);
}
}
}
else{
int x,y;
cin >> x >> y;
if (same(x,y)){
cout << "SUCCESS" << endl;
}
else{
cout << "FAIL" << endl;
}
}
}
}