题目
东南亚发生地震。ACM(亚洲合作医疗队)与膝上电脑建立了无线网络,但意外的余震袭击了网络中的所有电脑。电脑一台一台修好,网络也渐渐开始恢复了。由于硬件限制,每台计算机只能直接与距离它不超过d米的计算机通信。但是每台计算机都可以看作是其他两台计算机之间通信的中介,也就是说,如果计算机 A 和计算机 B 可以直接通信,或者有一台计算机 C 可以同时与 A 和计算机通信,那么计算机 A 和计算机 B 就可以通信。 B.
在修复网络的过程中,工人每时每刻都可以进行两种操作,修复一台计算机,或者测试两台计算机是否可以通信。你的工作是回答所有的测试操作。输入
第一行包含两个整数 N 和 d(1 <= N <= 1001, 0 <= d <= 20000)。这里 N 是计算机的数量,从 1 到 N 编号,D 是两台计算机可以直接通信的最大距离。在接下来的 N 行中,每行包含两个整数 xi, yi (0 <= xi, yi <= 10000),这是 N 台计算机的坐标。从第(N+1)行到输入结束,有操作,一一进行。每行包含以下两种格式之一的操作:
1. "O p" (1 <= p <= N),表示修复计算机 p。
2. "S p q" (1 <= p, q <= N),表示测试计算机p和q是否可以通信。
输入不会超过300000行。输出
对于每个测试操作,如果两台计算机可以通信,则打印“SUCCESS”,否则打印“FAIL”。样本输入
4 1 0 1 0 2 0 3 0 4 O 1 O 2 O 4 S 1 4 O 3 S 1 4
样本输出
FAIL SUCCESS
AC代码
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int n,m;
int f[1010];
int vis[1010][1010],fl[1010]; //vis标记两点间距离是否小于d,fl标记电脑是否被修过
float x[1010],y[1010];
int getf(int v)
{
if(f[v]==v)
return v;
else
{
f[v]=getf(f[v]);
return f[v];
}
}
void merge(int u,int v)
{
int t1,t2;
t1=getf(u);
t2=getf(v);
if(t1!=t2)
f[t2]=t1;
}
int main()
{
int n,d,i,j;
cin>>n>>d;
for(int i=1;i<=n;i++) //每个节点的根节点初始化为自己
f[i]=i;
for(i=1;i<=n;i++)
{
cin>>x[i]>>y[i];
}
for(i=1;i<=n;i++)
{
for(j=i;j<=n;j++)
{
if((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])<=d*d)
vis[i][j]=vis[j][i]=1; //如果这个点在距离d之内就标记
}
}
char c;
int a,b;
while(~scanf("%c",&c))
{
if(c=='O')
{
cin>>a;
fl[a]=1; //标记修过的电脑a
for(i=1;i<=n;i++)
if(i!=a&&vis[a][i]&&fl[i]) //a和i在距离d之内,且a和i是修过的电脑
merge(a,i);
}
if(c=='S')
{
cin>>a>>b;
if(getf(a)==getf(b)) //如果根节点一样就表示a和b连通
cout<<"SUCCESS"<<endl;
else
cout<<"FAIL"<<endl;
}
}
return 0;
}