• 【BZOJ2429】聪明的猴子


    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2429


    比较简单的一道题目。。。

    从一棵树出发蹦到其他所有树,实际上,把n-1条边就可以将这n个点连通,而最小生成树的最大权值又是所有生成树中最小的,因此我们需要构造一棵最小生成树,然后将m个猴子的跳跃距离和MST的最大边权比较,统计答案即可。

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 const int maxm = 505, maxn = 1e3 + 5;
     8 
     9 int monkey[maxm], treex[maxn], treey[maxn];
    10 
    11 struct Edge {
    12     int u, v;
    13     double w;
    14     bool operator < (const Edge& rhs) const {
    15         return w < rhs.w;
    16     }
    17 } edge[maxn * maxn / 2];
    18 
    19 inline int pw2(int x) {
    20     return x * x;
    21 }
    22 
    23 inline double dis(int i, int j) {
    24     return sqrt(pw2(treex[i] - treex[j]) + pw2(treey[i] - treey[j]));
    25 }
    26 
    27 int m, n, eid, fa[maxn];
    28 
    29 int dj_find(int i) {
    30     if (i == fa[i]) return i;
    31     else return fa[i] = dj_find(fa[i]);
    32 }
    33 
    34 inline void dj_merge(int a, int b) {
    35     fa[dj_find(a)] = dj_find(b);
    36 }
    37 
    38 inline double kruskal() {
    39     for (int i = 1; i <= n; ++i) fa[i] = i;
    40     sort(edge + 1, edge + eid + 1);
    41     int cnt = 0;
    42     for (int i = 1; i <= eid; ++i) {
    43         int u = edge[i].u, v = edge[i].v, w = edge[i].w;
    44         if (dj_find(u) != dj_find(v)) {
    45             dj_merge(u, v);
    46             if (++cnt == n - 1) return w;
    47         }
    48     }
    49     return edge[eid].w;
    50 }
    51 
    52 int main() {
    53     scanf("%d", &m);
    54     for (int i = 1; i <= m; ++i) scanf("%d", &monkey[i]);
    55     scanf("%d", &n);
    56     for (int i = 1; i <= n; ++i) scanf("%d%d", &treex[i], &treey[i]);
    57     for (int i = 1; i < n; ++i)
    58         for (int j = i + 1; j <= n; ++j) {
    59             edge[++eid].u = i;
    60             edge[eid].v = j;
    61             edge[eid].w = dis(i, j);
    62         }
    63     int ans = 0;
    64     double me = kruskal();
    65     for (int i = 1; i <= m; ++i)
    66         if (monkey[i] >= me) ++ans;
    67     printf("%d", ans);
    68     return 0;
    69 }
    AC代码
  • 相关阅读:
    CSharp程序员学Android开发---1.初识AndriodIDE,掌握工具使用
    生产者-消费者问题(2)
    c++顺序容器
    打印二叉树某一层次的值(重点)
    二叉树层次遍历
    搜索算法比较
    动态定义数组
    RMQ(range minimum/maximum query)即查询区间最大最小值。
    string 空值
    vector 下标操作
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9903053.html
Copyright © 2020-2023  润新知