您的位置:首页 > 理论基础 > 计算机网络

[FZYZOJ 1031] 无线网络

2015-06-03 15:47 253 查看

P1031 -- 无线网络

时间限制:1000MS 内存限制:65536KB

Description

有一个由n台计算机组成的无线网络。(n <= 1001) 正常情况下,每台计算机都能跟与它距离不超过d的任何计算机通讯。 (d <= 20000) 地震发生了。所有的计算机都陷入瘫痪。专家们试着一台一台地修复计算机,以恢复整个无线网络。有时在修复的过程中,他们需要测试一下某两台计算机能否通讯(如果他们能通过别的正常的计算机进行通讯,也算他们之间可以通讯,即"能否通讯"可以是间接的)。 你的任务,就是模拟修复网络的过程,并回答"能否通讯"的询问。

Input Format

第一行两个整数,N和d,N表示计算机的数目,d表示两台计算机直接可直接通讯的最大距离。接下来的N行,每行两个整数Xi,Yi,表示每台计算机的坐标。接下来有许多行,每行都是一个操作(或者是修复操作,或者是询问操作)。 操作的格式如下: O p (1 <= p <= N) 修复操作,表示修复编号为p的电脑; S p q (1 <= p, q <= N) 询问操作,询问编号为p和编号为q的电脑能否通讯。 如果一台电脑尚未被修复,则它不能和任何电脑通讯。

Output Format

对于每个询问操作:如果能够通讯,输出一行SUCCESS;如果无法通讯,输出一行FAIL

Sample Input

4 1
0 1
0 2
0 3
0 4
O 1
O 2
O 4
S 1 4
O 3
S 1 4

Sample Output

FAIL
SUCCESS

Hint

对于50%的数据,N <= 300, 操作次数 <= 10000; 对于100%的数据,N <= 1001, 操作次数 <= 300000。

【题解】

此题一看到题目就想到用并查集(或许是最近并查集的题目做了挺多的)

反正就是并查集,路径压一压就好(事实证明这道题路径不压比压还好!!!)

然后就对于每个的O操作,1...n扫一遍,更新一下即可

然而看起来会超时,实际并不会。

#include<bits/stdc++.h>
using namespace std;
int n,d;
int x[1002],y[1002],pre[1002];
bool vis[1002];
inline double getdist(int xz,int yz,int xy,int yy) {return sqrt((xz-xy)*(xz-xy)+(yz-yy)*(yz-yy));}
int findset(int x) {
int r=x;
while(pre[r]!=r) r=pre[r];
int i=x,j;
while(i!=r) {
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
int main() {
scanf("%d%d",&n,&d);
for (int i=1;i<=n;++i) pre[i]=i;
char cs[2];
for (int i=1;i<=n;++i) scanf("%d%d",&x[i],&y[i]);
while(~scanf("%s",cs)) {
if (cs[0]=='S') {
int a,b;
scanf("%d%d",&a,&b);
int a1=findset(a),b1=findset(b);
if(a1==b1&&vis[a]&&vis[b]) printf("SUCCESS\n");
else printf("FAIL\n");
}
else {
int a;
scanf("%d",&a);
vis[a]=1;
for (int i=1;i<=n;++i) if(vis[i]&&i!=a&&getdist(x[a],y[a],x[i],y[i])<=d) pre[findset(i)]=findset(a);
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: