「HDU 1512」Monkey King

时间:2020-01-18
本文章向大家介绍「HDU 1512」Monkey King,主要包括「HDU 1512」Monkey King使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

曾经在森林里,有 N 只好斗的猴子。一开始,他们各自以自己的方式做事,彼此之间都不认识。但是猴子无法避免争吵,争吵只发生在两只彼此不认识的猴子之间。当发生这种情况时,两只猴子都将邀请他们中最坚强的朋友并进行决斗。当然,在决斗之后,两只猴子和那里所有的朋友彼此认识,即使这些猴子曾经发生过冲突,上面的争吵也不会再发生。

假设每只猴子都有一个强力值,在决斗后,该值将只减少为原始值的一半(即 10 减少为 5 , 5 减少为 2 )。

我们还假设每只猴子都认识自己。也就是说,当他是所有朋友中最坚强的人时,他本人将进行决斗。

HDU

分析

给每个猴子建一棵大根堆左偏树,当两个猴子成为朋友的时候,就把它们所在的左偏树合并,而找出最坚强的朋友,就返回它所在的左偏树的堆顶。减少朋友的强力值的话,先删除朋友,将权值减半再将该点作为一棵左偏树合并进原来的左偏树中就好了。

代码

//=========================
//  author:hliwen
//  date:2020.1.18
//=========================
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100005
#define il inline
#define re register
#define DEBUG puts("ok")
#define tie0 cin.tie(0),cout.tie(0)
#define fastio ios::sync_with_stdio(false)
#define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
using namespace std;
typedef long long ll;

template <typename T> inline void read(T &x) {
    T f = 1; x = 0; char c;
    for (c = getchar(); !isdigit(c); c = getchar()) if (c == '-') f = -1;
    for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    x *= f;
}

int n, m;
int val[N], fa[N], dis[N], rs[N], ls[N];

int merge(int x, int y) {
    if (!x || !y) return x + y;
    if (val[x] < val[y]) swap(x, y);
    rs[x] = merge(rs[x], y);
    fa[rs[x]] = x;
    if (dis[ls[x]] < dis[rs[x]]) swap(ls[x], rs[x]);
    dis[x] = dis[rs[x]] + 1;
    return x;
}

int pop(int x) {
    val[x] >>= 1;
    int y = fa[ls[x]] = fa[rs[x]] = merge(ls[x], rs[x]);
    ls[x] = rs[x] = 0;
    return fa[x] = fa[y] = merge(x, y);
}

int find(int x) {
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}

int main() {
    int x, y, ans;
    while (~scanf("%d", &n)) {
        for (int i = 1; i <= n; ++i) {
            read(val[i]);
            fa[i] = i;
            dis[i] = rs[i] = ls[i] = 0;
        }
        read(m);
        for (int i = 1; i <= m; ++i) {
            read(x), read(y);
            if (find(x) == find(y)) puts("-1");
            else {
                int fx = find(x), fy = find(y);
                ans = merge(pop(fx), pop(fy));
                printf("%d\n", val[ans]);
            }
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hlw1/p/12209579.html