zoukankan      html  css  js  c++  java
  • poj2236 并查集板子题

    题目大意:

      给你N台电脑和一个距离D,然后给你N台电脑的坐标xi,yi,0<=xi,yi<=10000,d<=20000,给你最多3e5次查询,每次查询中,(O x)表示修复了x号电脑,(S x y)表示询问x和y是否可以通信,返回查询结果(如果两台电脑距离在d之内,那么两台电脑可以相连)

    题解:

      一共3e5次查询,但是最多有1000个点,所以最多修复1000台电脑,枚举所有电脑,找到他周围可以连接的电脑,进行合并(一开始想的是,如果修复3e5次,直接时间爆炸,不过后来发现最多修1e3次,傻了。。。)给了10s,直接水过

      不知道为啥我开始想的时候是在连接的时候就进行合并,然后修复的时候再找边,一定是失了智。。。

    贴上代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #define mem(a,b) memeset(a,b,sizeof(b))
     5 using namespace std;
     6 const int maxn=1e3+10;
     7 int parent[maxn],vis[maxn],rank[maxn];
     8 int d,n;
     9 struct node
    10 {
    11     int x,y;
    12     node(){}
    13     node(int a,int b):x(a),y(b){}
    14 }pc[maxn];
    15 double len(node a,node b)
    16 {
    17     int x=a.x-b.x;
    18     int y=a.y-b.y;
    19     return sqrt(x*x+y*y);
    20 }
    21 int find(int x)
    22 {
    23     int k, j, r;
    24     r = x;
    25     while(r != parent[r])
    26         r = parent[r];
    27     k = x;
    28     while(k != r)
    29     {
    30         j = parent[k];
    31         parent[k] = r;
    32         k = j;
    33     }
    34     return r;
    35 }
    36 void merg(int x,int y)
    37 {
    38     int fx=find(x);
    39     int fy=find(y);
    40     if(rank[fx]<=rank[fy])
    41     {
    42         parent[fy]=fx;
    43         rank[fx]++;
    44     }
    45     else
    46     {
    47         parent[fx]=fy;
    48         rank[fy]++;
    49     }
    50 }
    51 void ini()
    52 {
    53     for(int i=1;i<=maxn;i++) parent[i]=i;
    54 }
    55 int main()
    56 {
    57     ini();
    58     scanf("%d%d",&n,&d);
    59     for(int i=1;i<=n;i++)
    60     {
    61         scanf("%d%d",&pc[i].x,&pc[i].y);
    62     }
    63     char s;
    64     while(cin>>s)
    65     {
    66         int a,b;
    67         if(s=='O')
    68         {
    69             scanf("%d",&a);
    70             if(vis[a]) continue;
    71             vis[a]=1;
    72             for(int i=1;i<=n;i++)
    73             {
    74                 if(a==i) continue;
    75                 if(len(pc[a],pc[i])>d) continue;
    76                 if(!vis[i]) continue;
    77                 else merg(a,i);
    78             }
    79             /*for(int i=1;i<=n;i++)
    80             {
    81                 printf("%d ",parent[i]);
    82             }puts("
    ");*/
    83         }
    84         else
    85         {
    86             scanf("%d%d",&a,&b);
    87             int fa=find(a);
    88             int fb=find(b);
    89             if(fa==fb) printf("SUCCESS
    ");
    90             else printf("FAIL
    ");
    91         }
    92     }
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    RTB交接
    awk命令详解
    Linux下的压缩解压缩命令详解
    inux下文件权限设置中的数字表示权限,比如777,677等,这个根据什么得来的
    jmeter接口测试教程
    kafka常用的操作命令
    hadoop常用的操作命令
    linux常用命令
    hive的常用命令
    用shell脚本写一个for循环
  • 原文地址:https://www.cnblogs.com/codeoosacm/p/10078731.html
Copyright © 2011-2022 走看看