题意是:给你一个坐标系,坐标系上有多个点。然后在每回合都会给你一个信息,这个信息可以是告诉你那个点是可用的,也可以是询问你某两个点之间是否可以相连。相连的前提为:两个点都是可用的。两点相连分为直接相连或者通过其他可用点来连接。
分析:首先我们要先去判断这两个点是否是可用点,如果不是可用点直接fail就好,然后再去判断这两个点是不是在同一个集合里面,如果在同一个集合就代表这两个点是可以相互连接的,原因是在char==‘O’时,我们就会进行一项操作,使得可用点之间组成一个集合,这个集合就是代表点之间可以相互连接,所以如果两个点如果在判断是否可以连接时不在一个集合,那么也是直接判断失败。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<cstdlib>
using namespace std;
const int maxn=1010;
int d;
struct Nod
{
int x,y;
}nod[maxn];
vector<int>vec;
int fa[maxn];
int vis[maxn];
bool cal_dis(int a,int b)
{
long long l=(nod[a].x-nod[b].x)*(nod[a].x-nod[b].x);
long long r=(nod[a].y-nod[b].y)*(nod[a].y-nod[b].y);
return sqrt(l+r)<=d?true:false;
}
int find(int x)
{
if(fa[x]==x) return x;
else return fa[x]=find(fa[x]);
}
bool check(int x,int y)
{
if(find(x)==find(y)) return true;
else return false;
}
void solve(int a,int b)
{
int flag=0;
if(vis[a]==1&&vis[b]==1)
{
if(find(a)==find(b)) flag=1;
else if(cal_dis(a,b)==true) flag=1;
}
if(flag==1)
{
printf("SUCCESS\n");
return;
}
else printf("FAIL\n");
}
void ini()
{
for(int i=1;i<=maxn;i++)
fa[i]=i;
memset(vis,0,sizeof vis);
vec.clear();
}
void process()
{
int a;
scanf("%d",&a);
vec.push_back(a);
vis[a]=1;
for(int i=0;i<vec.size()-1;i++)
{
if(find(vec[i])==find(a)) continue;
if(cal_dis(vec[i],a)==true) fa[fa[vec[i]]]=a;//这里要注意是修改父节点的fa值
}
}
int main()
{
ini();
int n;
scanf("%d %d",&n,&d);
for(int i=1;i<=n;i++)
scanf("%d %d",&nod[i].x,&nod[i].y);
getchar();
char op;
while(scanf("%c",&op)!=EOF)
{
if(op=='O') process();
else
{
int a,b;
scanf("%d %d",&a,&b);
solve(a,b);
}
getchar();
}
//system("pause");
return 0;
}