• [FZYZOJ 1031] 无线网络


    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扫一遍,更新一下即可

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

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,d;
     4 int x[1002],y[1002],pre[1002];
     5 bool vis[1002];
     6 inline double getdist(int xz,int yz,int xy,int yy) {return sqrt((xz-xy)*(xz-xy)+(yz-yy)*(yz-yy));}
     7 int findset(int x) {
     8     int r=x;
     9     while(pre[r]!=r) r=pre[r];
    10     int i=x,j;
    11     while(i!=r) {
    12         j=pre[i];
    13         pre[i]=r;
    14         i=j;
    15     }
    16     return r;
    17 }
    18 int main() {
    19     scanf("%d%d",&n,&d);
    20     for (int i=1;i<=n;++i) pre[i]=i;
    21     char cs[2];
    22     for (int i=1;i<=n;++i) scanf("%d%d",&x[i],&y[i]);
    23     while(~scanf("%s",cs)) {
    24         if (cs[0]=='S') {
    25             int a,b;
    26             scanf("%d%d",&a,&b);
    27             int a1=findset(a),b1=findset(b);
    28             if(a1==b1&&vis[a]&&vis[b]) printf("SUCCESS
    ");
    29             else printf("FAIL
    ");
    30         }
    31         else {
    32             int a;
    33             scanf("%d",&a);
    34             vis[a]=1;
    35             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);
    36         }
    37     }
    38     return 0;
    39 }
    View Code
    这篇文章由TonyFang发布。 所有解释权归TonyFang所有。 Mailto: tony-fang@map-le.net
  • 相关阅读:
    【秒懂音视频开发】10_PCM转WAV
    【秒懂音视频开发】09_播放PCM
    【秒懂音视频开发】08_音频录制02_编程
    【秒懂音视频开发】07_音频录制01_命令行
    【秒懂音视频开发】06_Qt开发基础
    高考数学考点关联表[Ⅳ]
    高考数学考点关联表[Ⅲ]
    高考数学考点关联表[Ⅱ]
    高考数学考点关联表[Ⅰ]
    反比例函数
  • 原文地址:https://www.cnblogs.com/TonyNeal/p/fzyzoj1031.html
Copyright © 2020-2023  润新知