题意:一张图上分布着n台坏了的电脑,并知道它们的坐标。两台修好的电脑如果距离<=d就可以联网,也可以通过其他修好的电脑间接相连。给出操作“O x”表示修好x,给出操作“S x y”,请你判断x和y在此时有没有连接上。
思路:并查集
AC代码:
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
int dis;
int x[1002][1002];
int y[1002][1002];
int pre[20000],v[20000];
struct point
{
int x;
int y;
}p[1002];
int distance(int a,int b,int c,int d)
{
if(((a-c)*(a-c)+(b-d)*(b-d))<=(dis*dis))
return true;
else
return false;
}
int find(int x)
{
if(pre[x]==x)
return x;
else
{
int a=find(pre[x]);
pre[x]=a;
return pre[x];
}
}
bool same(int a,int b)
{
return find(a)==find(b);
}
void unite(int a,int b)
{
int c=find(a);
int d=find(b);
if(c!=d)// 注意!!合并的是啥?父集!!
pre[d]=c;
// if(!same(a,b))//XXXXX错
// {
// pre[a]=b;
// pre[b]=a;
// }
}
int main()
{
int n,a,b;
cin>>n>>dis;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
}
for(int i=1;i<=n;i++)
{
pre[i]=i;
v[i]=0;
}
char s;
while(cin>>s)//此处scanf超时
{
if(s=='O')
{
cin>>a;
v[a]=1;
for(int i=1;i<=n;i++)
{
if(i!=a&&v[i]&&distance(p[a].x,p[a].y,p[i].x,p[i].y))//注意!!要有v[i]!=0这个条件否则将没修好的电脑也算上了
unite(a,i);
}
}
else if(s=='S')
{
cin>>a>>b;
if(same(a,b))
cout<<"SUCCESS"<<endl;
else
cout<<"FAIL"<<endl;
}
}
}