zoukankan      html  css  js  c++  java
  • [APIO2012]派遣 左偏树

    P1552 [APIO2012]派遣

    题面

    考虑枚举每个节点作为管理者,计算所获得的满意程度以更新答案。对于每个节点的计算,贪心,维护一个大根堆,每次弹出薪水最大的人。这里注意,一旦一个人被弹出,那么不再可能出现在其祖先们的最优解里(废话),所以使用可并堆左偏树优化复杂度。

    #include <cstdio>
    #include <algorithm>
    #define MAXN 100010
    #define MAX(A,B) ((A)>(B)?(A):(B))
    #define LL long long
    using namespace std;
    int n,m,rot;
    LL ans;
    int head[MAXN],nxt[MAXN*2],vv[MAXN*2],tot;
    inline void add_edge(int u, int v){
        vv[++tot]=v;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    int val[MAXN],lead[MAXN],sl[MAXN],sr[MAXN],dis[MAXN];
    int merge(int a, int b){
        if(a==0||b==0) return a+b;
        if(val[a]<val[b]) swap(a, b);
        sr[a]=merge(sr[a], b);
        if(dis[sl[a]]<dis[sr[a]]) swap(sl[a], sr[a]);
        dis[a]=dis[sr[a]]+1;
        return a;
    }
    int root[MAXN],cnt,sz[MAXN],sum[MAXN];
    void dfs(int u){
        root[u]=u;sz[u]=1;sum[u]=val[u];
        for(int i=head[u];i;i=nxt[i]){
            int v=vv[i];
            dfs(v);
            root[u]=merge(root[u], root[v]);
            sum[u]+=sum[v];
            sz[u]+=sz[v];
            while(sum[u]>m){
                sum[u]-=val[root[u]];
                sz[u]-=1;
                root[u]=merge(sl[root[u]], sr[root[u]]);
            }
        }
        ans=MAX(ans, (LL)sz[u]*lead[u]);
    }
    int main()
    {
        scanf("%d %d", &n, &m);
        for(int i=1;i<=n;++i){
            int v;scanf("%d", &v);
            if(v==0) rot=i;
            add_edge(v,i);
            scanf("%d %d", &val[i], &lead[i]);
        }
        dfs(rot);
        printf("%lld", ans);
        return 0;
    }
    
  • 相关阅读:
    pt-tcp-model
    (转)从史上八大MySQL宕机事故中学到的经验
    pt-query-digest
    DNS生效时间
    Python之uuid模块
    一个IO的传奇一生
    Python之Queue模块
    利用freemarker 静态化网页
    FreeMarker教程
    模板引擎freemarker的简单使用教程
  • 原文地址:https://www.cnblogs.com/santiego/p/11039233.html
Copyright © 2011-2022 走看看