Wireless Network
东南亚发生地震。ACM(亚洲合作医疗队)已经建立了一个无线网络与圈电脑,但一个意外的余震袭击,所有的计算机在网络全部被打破。电脑一个接一个地修好了,网络也渐渐开始运转起来。由于硬件的限制,每台计算机只能直接与距离它不到 d 米的计算机进行通信。但是,每台计算机都可以被视为另外两台计算机之间的通信中介,也就是说,如果计算机A和计算机B可以直接通信,或者计算机C可以与A和B进行通信,那么计算机A和计算机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
行。输出
对于每个测试操作,如果两台计算机可以通信,则打印"成功",如果没有,则打印"失败"。
示例输入
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
题意描述:给计算机的数量以及两台计算机可通信的最大距离,然后是这些计算机的坐标,O代表修复计算机即某计算机可以和外界连通,S代表测试某两个计算机是否可以连通,可连通输SUCCESS,不可以输出FAIL 解题思路:可以利用并查集,先利用两个数组存每个计算机的坐标,因为并不是每个计算机都可以和其他计算机连通,所以只需要合并可以连通的计算机就行了,可以利用数组标记一下,代表这个计算机可以连通外界;同时计算机连通有距离限制,所以我们还要求可以连通的计算机间的距离,如果它们不超过最大距离,就让它们和其他标记过的计算机合并(也就是前面标记过的可以与其他计算机连通的计算机)。最后判断我们测试的两个计算机是否在一个集合里,此处要求这两个计算机本身必须是可以与外界连通的,然后按情况输出即可。 注意:注意输入格式。
#include<stdio.h>
int x[10500],y[10500],f[10500],book[1050];
//递归找爹 合并联通的计算机
int getf(int v)
{
if(f[v]==v)
return v;
else
{
f[v]=getf(f[v]);
return f[v];
}
}
//合并两个子集
void merge(int v,int u)
{
int t1,t2;
t1=getf(v);
t2=getf(u);
if(t1!=t2)
{
f[t2]=t1;
}
return ;
}
int main(void)
{
int n,m,d,a,b;
char s[10];
scanf("%d %d",&n,&d);//计算机数量,最大距离
for(int i=1;i<=n;i++)
{
f[i]=i;
scanf("%d %d",&x[i],&y[i]);
}
while(~scanf("%s",s))
{
if(s[0]=='O')
{
scanf("%d",&m);//哪些计算机可通
book[m]=1;
for(int i=1;i<=n;i++)
{
if(book[i]==1&&(x[m]-x[i])*(x[m]-x[i])+(y[m]-y[i])*(y[m]-y[i])<=d*d)
merge(m,i);//合并
}
}
else//计算某两个是否通
{
scanf("%d %d",&a,&b);
if(getf(a)==getf(b)&&book[a]&&book[b])
printf("SUCCESS\n");
else
printf("FAIL\n");
}
}
return 0;
}