1、题目大意:给一棵树和M值,每个点有两个权值C和L,选x个点,这x个点的C值的和不能超过M,且这x个点如果都在某个子树内

定义满意度为x*这个子树的根的L值

2、分析:这是一道可并堆的题目,我们考虑每一个子树,我们想让其中的选的点尽量多但是C和却不超过M

我们只需取C值最小的,次小的,第三小的……直到不能选为止,这个不是很简单吗,不就是一个堆吗

不对,难道对于每一个子树都要建一个堆吗,那不是爆了吗,我们只需把这个子树的所有子节点所在的堆全都合并

还要再加上这个子树的根节点,这样就可以了

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1000000
#define LL long long
struct merge_heap{
    int l[M], r[M], d[M], value[M];
    void init(){
        memset(l, 0, sizeof(r));
        memset(r, 0, sizeof(r));
        memset(d, 1, sizeof(d));
    }
    int merge(int x, int y){
        if(!x) return y;
        if(!y) return x;
        if(value[x] < value[y]) swap(x, y);
        r[x] = merge(r[x], y);
        if(d[l[x]] < d[r[x]]){
            swap(l[x], r[x]);
        }
        d[x] = d[l[x]] + 1;
        return x;
    }
} wt;
int n, m;
int C[M], L[M];
int head[M], Next[M], son[M], tot;
int tree[M];
int sum[M], size[M];
LL ans = 0;
void dfs(int x){
    for(int i = head[x]; i != -1; i = Next[i]){
        dfs(son[i]);
        sum[x] += sum[son[i]];
        size[x] += size[son[i]];
        tree[x] = wt.merge(tree[x], tree[son[i]]);
        while(sum[x] > m){
            size[x] --;
            sum[x] -= wt.value[tree[x]];
            tree[x] = wt.merge(wt.l[tree[x]], wt.r[tree[x]]);
        }
    }
    ans = max((LL)L[x] * (LL)size[x], ans);
}
int main(){
    memset(head, -1, sizeof(head));
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++){
        int fa;
        scanf("%d%d%d", &fa, &C[i], &L[i]);
        wt.value[i] = C[i];
        Next[++ tot] = head[fa];
        head[fa] = tot;
        son[tot] = i;
        sum[i] = C[i];
        size[i] = 1;
    }
    wt.init();
    for(int i = 1; i <= n; i ++) tree[i] = i;
    dfs(0);
    printf("%lld\n", ans);
    return 0;
} 

最新文章

  1. c++中this指针的用法
  2. codevs1021 玛丽卡
  3. 谁也无法挡住我访问Google---使用Nginx反向代理攻略
  4. [.net 面向对象程序设计进阶] (2) 正则表达式 (一) 快速入门
  5. Python脚本模拟登录网页之ZiMuZu篇
  6. ModelAndView学习整理
  7. 细谈HTML5
  8. IOS之swift第一课基础代码
  9. Oracle的rowid结构解析
  10. StringBuilder字符串拼接类
  11. Tortoisegit 记住用户名和密码
  12. Mybatis批量更新数据
  13. iOS MVVM 前世今生
  14. 如何在sublime中安装使用eslint
  15. Linux_window与linux之间文件互传,上传下载
  16. 西门子flexable创建画面
  17. [SDOI 2009]Elaxia的路线
  18. 60道Python面试题&amp;答案精选!找工作前必看
  19. 2018-2019-2 网络对抗技术 20165305 Exp4 恶意代码分析
  20. 第一册:lesson seventy one.

热门文章

  1. 嵌入式Linux系统开发环境搭建
  2. js005-引用类型
  3. sql 时间查询 /sql中判断更新或者插入/查询一年所有双休日
  4. angularjs中ng-selected使用方法
  5. Socket通信的理解
  6. 转换流——OutputStreamWriter类与InputStreamReader类
  7. WebApp基础01-设置读取assets目录下文件
  8. UITableViewCell的separator分隔线设置失效
  9. Ansible简介及常用模块
  10. Redis-cluster集群【第二篇】:redis持久化