并查集_无线网络

来源:互联网 发布:咸鱼如何申请淘宝介入 编辑:程序博客网 时间:2024/05/22 15:40

题目描述
一场地震在东南亚发生了。不幸的是ACM组织通过电脑建立的无线网络遭到了毁灭性的影响—--网络中所有的电脑都损坏了。在陆续的维修电脑之后,无线网络有逐渐开始再一次运作了。由于硬件的制约,每两台电脑只能保持不超过d米的距离,才可以直接进行通讯。但是每台电脑又可以作为其它两台电脑通讯的中介点,也就是说假设A电脑与B电脑不在能直接通讯的的范围内,但是它们可以通过同时能与A和B电脑通讯的C电脑建立间接通讯关系。
在维修的过程中,维修者可以进行两种操作:维修一台电脑或者检测两台电脑之间是否能够通讯。你的任务就是解答每一次的检测操作。
输入
第一行包含两个整数N和d (1 <= N <= 1001, 0 <= d <= 20000).N表示电脑的数量,电脑编号从1开始到N,d为两台能直接通讯的电脑所需保持的距离的最大值。在接下来的N行里,每行包含两个整数xi, yi (0 <= xi, yi <= 10000),表示N台电脑的坐标。接下来的一系列的输入都表示维修者的操作,每种操作都是以下两种中的一种:
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

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define same(x,y) Find(x)==Find(y)
#define mul(x) x*x
const int maxn=1005;
int par[maxn],flag[maxn],united[maxn][maxn];
int Find(int x)
{
return par[x]==x?x:Find(par[x]);
}
void unite(int x,int y)
{
x=Find(x);
y=Find(y);
if(x!=y) par[x]=y;
}
void init(int n)
{
for(int i=1; i<=n; i++)
{
par[i]=i;
flag[i]=0;
}
}
int main()
{
int n,p,q,x[maxn],y[maxn];
double d;
memset(united,0,sizeof(united));
scanf("%d%lf",&n,&d);
init(n);
for(int i=1; i<=n; i++)
scanf("%d%d",&x[i],&y[i]);
for(int i=1; i<n; i++)
for(int j=i+1; j<=n; j++)
{
double t1=x[i]-x[j],t2=y[i]-y[j];
if(sqrt(mul(t1)+mul(t2))<=d)
{
united[i][j]=1;
united[j][i]=1;
}
}
char op;
while(~scanf("%c",&op))
{
if(op=='O')
{
scanf("%d",&p);
flag[p]=1;
for(int i=1; i<=n; i++)
if(flag[i]&&united[i][p])
unite(p,i);
}
if(op=='S')
{
scanf("%d%d",&p,&q);
printf("%s\n",same(p,q)?"SUCCESS":"FAIL");
}
}
return 0;
}

原创粉丝点击