【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=2809

【题目大意】

  给出一棵树,求出每个点有个权值,和一个乘算值,请选取一棵子树,
  并在这个子树上选择一些节点,使得根节点的乘算值乘上选取的节点数价值最大,
  并且权值和不超过给定的限制

【题解】

  我们在树上做dfs,计算每个点作为子树根节点时候的价值,
  维护可并的权值大根堆,自下而上合并,当发现权值和大于限制的时候pop根节点即可。

【代码】

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
const int N=100010;
int x,n,m,cnt,tot;
vector<int> v[N];
LL ans,sum[N],size[N];
int C[N],L[N],root[N];
struct SHeap{
int v[N],l[N],r[N];
int merge(int x,int y){
if(x==0||y==0)return x+y;
if(v[x]<v[y])swap(x,y);
r[x]=merge(r[x],y);
swap(l[x],r[x]);
return x;
}void pop(int &x){x=merge(l[x],r[x]);}
int top(int x){return v[x];}
}heap;
void dfs(int x){
root[x]=++tot; heap.v[tot]=C[x];
size[x]=1; sum[x]=C[x];
for(int i=0;i<v[x].size();i++){
dfs(v[x][i]);
sum[x]+=sum[v[x][i]];
size[x]+=size[v[x][i]];
root[x]=heap.merge(root[x],root[v[x][i]]);
}
while(sum[x]>m){
sum[x]-=heap.top(root[x]);
heap.pop(root[x]);
size[x]--;
}ans=max(ans,size[x]*L[x]);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&x,&C[i],&L[i]);
v[x].push_back(i);
}dfs(1);
printf("%lld\n",ans);
return 0;
}

最新文章

  1. 如果没有Visual Studio 2015,我们如何创建.NET Core项目 ?
  2. PBOC金融IC卡,卡片与终端交互的13个步骤,简介-第二组(转)
  3. LayoutInflater的infalte()
  4. java的分层开发
  5. 21. Clone Graph
  6. PHP 错误与异常 笔记与总结(6)将错误日志保存在系统日志中
  7. Qt之事件系统
  8. JavaScript 三种绑定事件方式之间的区别
  9. Webx常用接口
  10. hibernate.cfg.xml配置(Oracle+c3p0)
  11. Unsupported major.minor version 52.0 处理方式
  12. AFURLRequestSerialization
  13. zookeeper curator处理会话过期session expired
  14. python 网络爬虫与信息提取 学习笔记day4
  15. JAVA应用程序转换为Applet
  16. Go指南练习_斐波纳契闭包
  17. aspose 小记
  18. matlab中将矩阵按照行打乱顺序的一个例子
  19. Redis批量查询删除KEYS
  20. umount 强制卸载

热门文章

  1. Different Integers(牛客多校第一场+莫队做法)
  2. Tunnel Warfare(HDU1540+线段树+区间合并)
  3. 【ALB学习笔记】基于多线程方式的串行通信接口数据接收案例
  4. 爬虫--Urllib库详解
  5. HTML -- get与post提交方式的区别 -- (转)
  6. Python模块学习 - openpyxl
  7. Python学习笔记 - day13 - 进程与线程
  8. Linux汇编教程03:大小比较操作
  9. 檢查 cpu 的全部 gpio 狀態及設定
  10. gnu app url[web][5星]