• BZOJ 2429: [HAOI2006]聪明的猴子 MST


    2429: [HAOI2006]聪明的猴子

    Description

    在一个热带雨林中生存着一群猴子,它们以树上的果子为生。昨天下了一场大雨,现在雨过天晴,但整个雨林的地
    表还是被大水淹没着,部分植物的树冠露在水面上。猴子不会游泳,但跳跃能力比较强,它们仍然可以在露出水面
    的不同树冠上来回穿梭,以找到喜欢吃的果实。现在,在这个地区露出水面的有N棵树,假设每棵树本身的直径都
    很小,可以忽略不计。我们在这块区域上建立直角坐标系,则每一棵树的位置由其所对应的坐标表示(任意两棵树
    的坐标都不相同)。在这个地区住着的猴子有M个,下雨时,它们都躲到了茂密高大的树冠中,没有被大水冲走。由
    于各个猴子的年龄不同、身体素质不同,它们跳跃的能力不同。有的猴子跳跃的距离比较远(当然也可以跳到较近
    的树上),而有些猴子跳跃的距离就比较近。这些猴子非常聪明,它们通过目测就可以准确地判断出自己能否跳到
    对面的树上。【问题】 现已知猴子的数量及每一个猴子的最大跳跃距离,还知道露出水面的每一棵树的坐标,你
    的任务是统计有多少个猴子可以在这个地区露出水面的所有树冠上觅食。

    Input

    第1行为一个整数,表示猴子的个数M(2<=M<=500);
    第2行为M个整数,依次表示猴子的最大跳跃距离(每个整数值在1--1000之间);
    第3行为一个整数表示树的总棵数N(2<=N<=1000);
    第4行至第N+3行为N棵树的坐标(横纵坐标均为整数,范围为:-1000--1000)。
    (同一行的整数间用空格分开)

    Output

    包括一个整数,表示可以在这个地区的所有树冠上觅食的猴子数

    Sample Input

    4
    1 2 3 4
    6
    0 0
    1 0
    1 2
    -1 -1
    -2 0
    2 2

    Sample Output

    3

    思路:

      题意即是求出最大的最小间距, 发现可以弄一张图做最小瓶颈生成树, 直接上Kruscal就好。a[i] *= a[i] 是防止曼哈顿距离开根的时候失精。

    代码:

     1 #include <algorithm>
     2 #include <cmath>
     3 #include <cstdio>
     4 using namespace std;
     5 int fa[1200];
     6 struct edge {
     7     int s, t;
     8     int v;
     9     bool operator < (const edge x) const {
    10         return v < x.v;
    11     }
    12 }e[1100000];
    13 int cnt;
    14 int maxn = 0;
    15 int n, m;
    16 int x[1200], y[1200];
    17 int a[600];
    18 int dist(int i, int j) {
    19     return (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
    20 }
    21 int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
    22 void kruscal() {
    23     sort(e+1, e+cnt+1);
    24     for(int i=1;i<=m;i++) fa[i]=i;
    25     for(int i=1;i<=cnt;i++) {
    26         int dx = find(e[i].s), dy = find(e[i].t);
    27         if(dx!=dy) {
    28             fa[dx] = dy;
    29             maxn = e[i].v;
    30         }
    31     }
    32 }
    33 int main() {
    34     scanf("%d", &n);
    35     for(int i=1;i<=n;i++) scanf("%d" ,&a[i]), a[i]*=a[i];
    36     scanf("%d", &m);
    37     for(int i=1;i<=m;i++) scanf("%d%d", &x[i], &y[i]);
    38     for(int i=1;i<=m;i++) {
    39         for(int j=i+1;j<=m;j++) {
    40             e[++cnt].s = i; e[cnt].t = j;
    41             e[cnt].v = dist(i, j);
    42         }
    43     }
    44     kruscal();
    45     int ans = 0;
    46     for(int i=1;i<=n;i++) if(a[i]>=maxn) ans++;
    47     printf("%d
    ",  ans);
    48 }
    View Code
  • 相关阅读:
    yarn安装ant-报错
    Linux扩展分区记录
    转载--tomcat调优
    转发:tomcat的acess_log打印post请求参数,分析日志
    经纬度差和米单位的换算
    loadrunner 11 安装与使用
    前端知识图谱
    linux-nc命令介绍
    双网卡设置(转:https://www.cnblogs.com/visionfeng/p/5825078.html)
    网络设备介绍
  • 原文地址:https://www.cnblogs.com/Tobichi/p/9204409.html
Copyright © 2020-2023  润新知