Description
An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have set up a wireless network with the lap computers, but an unexpected aftershock attacked, all computers in the network were all broken. The computers are repaired one by one, and the network gradually began to work again. Because of the hardware restricts, each computer can only directly communicate with the computers that are not farther than d meters from it. But every computer can be regarded as the intermediary of the communication between two other computers, that is to say computer A and computer B can communicate if computer A and computer B can communicate directly or there is a computer C that can communicate with both A and B.
In the process of repairing the network, workers can take two kinds of operations at every moment, repairing a computer, or testing if two computers can communicate. Your job is to answer all the testing operations.
题目大意:一场地震毁了所有的电脑(我该说earthquake的威力大呢?还是电脑太RUO。。。)给出各电脑的坐标,两个电脑可以相连,当两电脑可以直接相连或者有一个中间电脑可以使之分别与中间电脑直接相连。两种操作:O ———修复电脑;S——查询两电脑能否连接,可以就输出“SUCCESS”,否则输出“FAIL”。
思路:预处理各电脑间的距离,简单的并查集,在线做法,每次修一台电脑都要穷举所有距离小于等于d的电脑,并更新。
(距离是欧拉距离,用平方保存就好了,注意d要先平方)
code:
#include<iostream>
#include<cstdio>
using namespace std;
int dis[1010][1010]={0},ad[1010][2]={0},fa[1010]={0};
bool visit[1010]={false};
int rool(int x)
{
if (fa[x]!=x) fa[x]=rool(fa[x]);
return fa[x];
}
int main()
{
int n,i,j,r1,r2,d,a,b;
char kind;
cin>>n>>d;
d=d*d;
for (i=1;i<=n;++i)
fa[i]=i;
for (i=1;i<=n;++i)
{
scanf("%d%d",&ad[i][0],&ad[i][1]);
for (j=1;j<i;++j)
dis[j][i]=dis[i][j]=(ad[i][0]-ad[j][0])*(ad[i][0]-ad[j][0])+
(ad[i][1]-ad[j][1])*(ad[i][1]-ad[j][1]);
}
while (scanf("%*c%c",&kind)==1)
{
if (kind=='O')
{
scanf("%d",&a);
r1=rool(a);
for (i=1;i<=n;++i)
if (dis[i][a]<=d&&visit[i])
{
r2=rool(i);
if (r1!=r2)
fa[r2]=r1;
}
visit[a]=true;
}
else
{
scanf("%d%d",&a,&b);
r1=rool(a);
r2=rool(b);
if (r1!=r2)
printf("%s\n","FAIL");
else printf("%s\n","SUCCESS");
}
}
}