6.Bzoj2809 [Apio2012]dispatching (左偏树

Posted gzygzy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了6.Bzoj2809 [Apio2012]dispatching (左偏树相关的知识,希望对你有一定的参考价值。

刚开始怎么都不会做.如果M比较小,还可以用树形动态做
后来才发现读错题目了
然后就是一个比较容易的左偏树题目
然后贪心的考虑,肯定把小值选上,直到总和 <= M且不能再加剩下的
首先考虑每一个点作为管理者的贡献
然后继续贪心的考虑
一次次弹出最大值
直到里面的和 <= M是最优的
左偏树维护一下即可.
可是好难写啊。。。。。。。
维护好多东西啊....
维护左偏树的和,左偏树结点的个数
开了longlong,竟然一遍过了!!(震惊

//卡常记录 535ms ->  480ms 
#include <iostream>
#include <cstdio>
#define rep(i , x, p) for(register int i = x;i <= p;++ i)
#define sep(i , x, p) for(int i = x;i >= p;-- i)
#define gc getchar()
#define pc putchar
#define ll long long
inline int read() {int x = 0,f = 1;char c = gc;while(c < ‘0‘ || c > ‘9‘) {if(c == ‘-‘)f = -1;c = gc;}while(c >= ‘0‘ && c <= ‘9‘) {x = x * 10 + c - ‘0‘;c = gc;}return x * f;}
void print(int x) {if(x < 0) pc(‘-‘) , x = -x;if(x >= 10) print(x / 10);pc(x % 10 + ‘0‘);}
using std::swap;
using std::max;
using std::min;
const int maxN = 100000 + 7;

int size[maxN] , M, n, w[maxN];;
ll sum[maxN];
//f表示这个点最多可以选择多少个点.
//sum表示堆里元素的和. 
//w表示管理值 

struct Node {
    int lson , rson, key, dis;
}P[maxN];

struct Edge {
    int v , nex;
}Map[maxN];
int head[maxN] , num;

void add_Node(int u,int v) {
    Map[++ num] = (Edge) {v , head[u]};
    head[u] = num;
    return ;
} 

int Merge(int x,int y) {
    if(!x || !y) return x + y;
    if(P[x].key < P[y].key) swap(x , y);
    P[x].rson = Merge(P[x].rson , y);
    if(P[P[x].rson].dis > P[P[x].lson].dis) swap(P[x].lson , P[x].rson);
    P[x].dis = P[P[x].rson].dis + 1;
    return x;
}

inline int Dele(int x) {return Merge(P[x].lson , P[x].rson);}

int dfs(int now) {
    int top = now , tmp_size = 1;
    ll tmp_sum = P[now].key;
    for(int i = head[now];i;i = Map[i].nex) {
        int v = Map[i].v;
        int q = Merge(top , dfs(v));
        tmp_sum += sum[v];
        tmp_size += size[v];
        top = q;
    } 
    while(tmp_sum > M) {
        tmp_sum -= P[top].key;
        int q = Dele(top);tmp_size --;
        top = q;
    }
    sum[now] = tmp_sum;
    size[now] = tmp_size; 
    return top;
}

int main() {
    n = read();M = read();
    int B , C, L;
    rep(i , 1, n) {
        B = read();
        add_Node(B , i); 
        P[i].key = read(); 
        w[i] = read();
    }
    dfs(1); 
    ll ans = 0;
    rep(i , 1, n) ans = max((ll)size[i] * w[i] , ans);
    printf("%lld",ans);
    return 0;
} 












以上是关于6.Bzoj2809 [Apio2012]dispatching (左偏树的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ2809 [Apio2012]dispatching

APIO2012BZOJ2809派遣dispatching

BZOJ2809: [Apio2012]dispatching

2809: [Apio2012]dispatching 可并堆 左偏树

Bzoj2809 [Apio2012]dispatching

BZOJ2809APIO2012dispatching