题目链接:https://cn.vjudge.net/problem/POJ-2236
题意:给你一些电脑的坐标;由于硬件的限制每台电脑哪怕修好了,也只能在d范围内通讯,如果A可以和B通讯,C跟A相距很远不能通讯,但如果和B可以通讯,那么A-B-C都能通讯;
PS:考查并查集,当电脑修好了,并且这两台电脑在D范围内,则union_nood;
见代码
#include <iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
const int N = 1005;
bool v[N];
int f[N],Rank[N]; // f记录父亲节点,Rank 记录该树的高度;优先将Rank小的放到大的集合,也就是压缩路径;
int n,d,dx[N],dy[N],repair[N]={0};//防止 树过长 导致find函数找爸爸要找很久
bool dis(int x,int y){ //判断是否在D内
double di=abs((dx[x]-dx[y])*(dx[x]-dx[y])+((dy[x]-dy[y])*(dy[x]-dy[y])));
if(di<=double (d*d))return true;
else
return false;
}
int find_root(int x){ //寻找跟节点
if(f[x]==x)
return x;
while(x!=f[x])
x=f[x];
return x;
}
void union_nood(int x,int y){ //合并
int p=find_root(x);
int q=find_root(y);
if(p==q)return ;
if(p!=q){
if(Rank[p]>Rank[q])
f[q]=p;
else if(Rank[p]<Rank[q])
f[p]=q;
else{
f[q]=p;
Rank[p]++;
}
}
}
int main()
{
cin>>n>>d;
f[0]=0;
for(int i=1;i<=n;i++){
cin>>dx[i]>>dy[i];
f[i]=i;
Rank[i]=0;
}
char oper;
int len=0;
//for(int i=1;i<=n;i++)cout<<dx[i]<<' '<<dy[i]<<endl;
while(cin>>oper){
int x,y;
if(oper=='O'){
cin>>x;
v[x]=true;
repair[len++]=x;
for(int i=0;i<len-1;i++){
if(repair[i]!=x && dis(repair[i],x))
union_nood(repair[i],x);
}
}
else if(oper=='S'){
cin>>x>>y;
if(find_root(x)==find_root(y)&&v[x]&&v[y])
printf("SUCCESS\n");
else
printf("FAIL\n");
}
}
return 0;
}