zoukankan      html  css  js  c++  java
  • BZOJ 2809: [Apio2012]dispatching(左偏树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2809

    题意:

    思路:
    最简单的想法就是枚举管理者,在其子树中从薪水低的开始选起,但是每个节点都这样处理的话就会重复计算。比如说,现在有两棵子树y,z已经处理好了,然后有一个顶点x连接着这两棵子树,现在要求的是当x为管理者时的最大满意度,其实没必要再去遍历所有x的子节点,因为y、z已经遍历过了,x所选忍者的肯定在y和z所选的忍者当中,如果它们的薪水和>m,那么就剃去最大的,直到薪水和<m。这样需要处理最大值和子树的合并,可以用左偏树来处理。

    #include<iostream>
    #include<cstdio>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int maxn = 100000+5;
    
    ll n,m;
    ll ans;
    int master;
    
    struct Heap
    {
        int l,r,dis,sz,root;
        ll salary,leading,sum;
    } t[maxn];
    
    vector<int> g[maxn];
    
    int merge(int x, int y)
    {
        if(x==0)  return y;
        if(y==0)  return x;
        if(t[y].salary>t[x].salary)  swap(x,y);
        t[x].r = merge(t[x].r,y);
        t[x].sum = t[t[x].l].sum + t[t[x].r].sum + t[x].salary;
        t[x].sz = t[t[x].l].sz + t[t[x].r].sz + 1;
        if(t[t[x].l].dis < t[t[x].r].dis)  swap(t[x].l,t[x].r);
        if(t[x].r == 0)  t[x].dis = 0;
        else t[x].dis = t[t[x].r].dis + 1;
        return x;
    }
    
    
    int pop(int &x)
    {
        x = merge(t[x].l,t[x].r);
    }
    
    int dfs(int u)
    {
        for(int i=0;i<g[u].size();i++)
        {
            int v = g[u][i];
            dfs(v);
            t[u].root = merge(t[u].root,t[v].root);
            while(t[t[u].root].sum>m)   pop(t[u].root);
        }
        ans = max(ans, t[t[u].root].sz*t[u].leading);
        return 0;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        scanf("%lld%lld",&n,&m);
        for(int i=1; i<=n; i++)
        {
            ll f,s,l;
            scanf("%lld%lld%lld",&f,&s,&l);
            if(f==0)  master = i;
            t[i].l=t[i].r=t[i].dis = 0;
            t[i].salary = t[i].sum = s;
            t[i].leading = l;
            t[i].root = i;
            t[i].sz = 1;
            g[f].push_back(i);
        }
        ans = 0;
        dfs(master);
        printf("%lld
    ",ans);
        return 0;
    }
    

      

  • 相关阅读:
    ThinkPHP如果表名有下划线需要用Model应该怎么做?
    JS三级联动实例
    Sublime的使用!emmet常用快捷键梳理
    MUI极简的JS函数
    Atitit 自然语言处理原理与实现 attilax总结
    Atitit 自然语言处理原理与实现 attilax总结
    Atitit  自动化gui 与 发帖机 技术
    Atitit  自动化gui 与 发帖机 技术
    Atitit 衡量项目的规模
    Atitit 衡量项目的规模
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7840955.html
Copyright © 2011-2022 走看看