http://www.lydsy.com/JudgeOnline/problem.php?id=2809
本来1A的,结果,ll没开全;
首先题目看懂,这个题目不长,但是要看懂;
看懂之后就会发现整个结构是树型的;
然后我们就可以搞事了呀;
和树形dp很像的;
我们维护n个大根堆;
不断把子节点合并到跟节点;
合并完了就不断弹出堆顶,就是工资最大的数;
直到当前堆里面全部工资小于等于m;
更新答案;
注意的是这里的一个堆,里面的参数的指向不清晰;
模版题目的指向是很清晰的;
这个就要严谨的逻辑关系;
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define Ll long long
using namespace std;
struct cs{
int to,next;
}a[100000];
struct heap{
Ll xx,yy,vv,money,num,fa;//vv是领导值,num堆内是有几个点,sum是总工资
Ll sum;
}q[100001];
int head[100001];
Ll n,m,x,y,z,ll,S;
Ll ans;
void init(int x,int y){
a[++ll].to=y;
a[ll].next=head[x];
head[x]=ll;
}
int merge(int x,int y){
if(!x)return y;
if(!y)return x;
if(q[x].money<q[y].money)swap(x,y);
q[x].yy=merge(q[x].yy,y);
swap(q[x].xx,q[x].yy);
return x;
}
void del(int x){//弹出堆顶
int xx=q[x].fa;
q[x].num--;
q[x].sum-=q[xx].money;
q[x].fa=merge(q[xx].xx,q[xx].yy);
}
void dfs(int x){
for(int k=head[x];k;k=a[k].next){
dfs(a[k].to);
q[x].num+=q[a[k].to].num;
q[x].sum+=q[a[k].to].sum;
q[x].fa=merge(q[x].fa,q[a[k].to].fa);
}
while(q[x].sum>m)del(x);
ans=max(ans,q[x].vv*q[x].num);
}
int main()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld%lld%lld",&x,&y,&z);
q[i].money=y;
q[i].sum=y;
q[i].num=1;
q[i].vv=z;
q[i].fa=i;
init(x,i);
if(!x)S=i;
}
dfs(S);
printf("%lld",ans);
}