题目大意: 经过一场大灾难所有的电脑都坏了,维修人员在一台一台的维修,只有修好的电脑之间才能连接,并且只有电脑之间的距离在d之间的才能连接
输如O进行修理某台电脑,输入S判断两台电脑之间能否连接
解题思路:并查集的简单应用,每修好一台电脑就把他和与它相距不超过d的电脑连起来,然后最后的时候直接查询父节点就可以了.
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
#define MAXN 1010
class Point
{
public:
int x, y;
Point(): x(0), y(0) {}
Point(int xx, int yy): x(xx), y(yy) {}
};
Point p[MAXN];
int par[MAXN]; //par[x]表示x的父节点
int dis[MAXN] ={0};
int n;
void Init() //初始化
{
int i;
for(i=0;i<=n;i++)
{
par[i] = i;
}
}
int Find(int x) //查询x的根节点并路径压缩
{
if(par[x]!=x)
par[x] = Find(par[x]);
return par[x];
}
void Union(int x,int y) //合并x和y所在集合
{
par[Find(x)] = Find(y);
}
int main()
{
int d,i;
//初始化
scanf("%d%d",&n,&d);
Init();
//输入坐标
for(i=1;i<=n;i++){
scanf("%d%d",&p[i].x,&p[i].y);
}
memset(dis, -1, sizeof(dis));
//操作
char ch[2];
int num,num1, num2,len=0;
while(scanf("%s",ch)!=EOF){
if(ch[0] == 'O'){
scanf("%d",&num);
for(int i = 1; i <= n; i++)
{
if(dis[i] != -1 && ((p[i].x-p[num].x)*(p[i].x-p[num].x) + (p[i].y-p[num].y)*(p[i].y-p[num].y) <= (d*d)))
Union(num, i);
}
dis[num] = 1;
}
else if(ch[0] == 'S')
{
scanf("%d%d",&num1,&num2);
if(Find(num1)==Find(num2)) //是否有路
printf("SUCCESS\n");
else
printf("FAIL\n");
}
}
return 0;
}