Wireless Network
原题链接https://vjudge.net/contest/350427#problem/A
题目有三个操作
首先给出每个电脑的位置坐标
然后是o和s代表修复和测试(不用在样例里找了,o跟0一模一样,前四行为坐标,剩下的都是o);
题目要求测试两台电脑能否通信,这是就有两个条件需要达成,1是两台电脑都被修复了,2是两台电脑要在距离范围之内,或者有电脑在中间传递。
这时候我们可以用并查集来处理,将满足距离的已经修复的电脑全部连接到一起,我们只需要判断是否在同一个集合有同一个根即可。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <queue>
using namespace std;
long long pre[10005];
long long n, d;
struct node
{
long long x;//x轴
long long y;//y轴
long long pre;//父集
} stu[10005];
long long find(long long x)
{
if (x == stu[x].pre)
{
return x;
}
return find(stu[x].pre);
}
void join(long long xx, long long xy)
{
//printf("%lld %lld\n",xx,xy);
// cout<<"*********"<<endl;
long long sx = find(xx);
long long sy = find(xy);
if (sx != sy)
{
if ((stu[xx].x - stu[xy].x) * (stu[xx].x - stu[xy].x) + (stu[xx].y - stu[xy].y) * (stu[xx].y - stu[xy].y) <= d * d)//如果没有在一个集合并且距离合适,就链接起来
{
// printf("d=%lld\n",(stu[xx].y-stu[xy].y)*(stu[xx].y-stu[xy].y));
// printf("%lld %lld %lld %lld",stu[xx].x,stu[xx].y,stu[xy].x,stu[xy].y);
// printf("链接\n");
stu[sx].pre = sy;
}
}
}
long long vis[10005];
int main()
{
scanf("%lld %lld", &n, &d);
long long i, j;
for (i = 1; i <= n; i++)
{
scanf("%lld %lld", &stu[i].x, &stu[i].y);
stu[i].pre = i;
}
// for(i=1;i<=n;i++)
// {
// printf("*******%lld %lld\n",stu[i].x,stu[i].y);
// }
memset(vis, 0, sizeof(vis));
char s;
long long m;
while (~scanf("\n%c", &s))//输入格式同getchar();
{
if (s == 'O')
{
scanf("%lld", &m);
vis[m] = 1;//将已经修复过的标记
for (i = 1; i <= n; i++)
{
if (vis[i] == 1 && i != m)//对于其他的已经修复的电脑进行判断
{
join(i, m);
}
}
}
else if (s == 'S')
{
long long sum1, sum2;
scanf("%lld %lld", &sum1, &sum2);
long long ss1 = find(sum1);
long long ss2 = find(sum2);
if (ss1 == ss2)//判断两台电脑是否在同一个集合
{
printf("SUCCESS\n");
}
else
{
printf("FAIL\n");
}
}
else
{
break;
}
/* for(i=1;i<=n;i++)
{
printf("%lld ",vis[i]);
}
printf("\n");*/
}
return 0;
}