题目大意
给的一棵以1为根树,每个点有代价
wi
w
i
,和价值
vi
v
i
,
一个点能共享价值当且仅当它以及它到1路径上的全部点被选中。
给定最大代价,求最大化价值。
题解
这是一棵树,每个点都在在它父亲被选中之后才能共享价值,
所以就是树形依赖背包。
先将dfs序求出来,
然后就可以随便dp一下了。
code
#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <time.h>
#define ll long long
#define N 5003
#define M 103
#define db double
#define P putchar
#define G getchar
#define inf 998244353
#define pi 3.1415926535897932384626433832795
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
ll abs(ll x){return x<0?-x:x;}
ll sqr(ll x){return x*x;}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}
int f[N][N*2],v[N],w[N],x,n,m,p,ans;
int nxt[N],to[N],lst[N],tot,dfn[N],g[N],id;
void ins(int x,int y)
{
nxt[++tot]=lst[x];
to[tot]=y;
lst[x]=tot;
}
void dfs(int x)
{
dfn[++id]=x;
for(int i=lst[x];i;i=nxt[i])
dfs(to[i]);
g[x]=id;
}
int main()
{
freopen("medicine.in","r",stdin);
freopen("medicine.out","w",stdout);
read(n);read(p);
read(w[1]);read(x);read(v[1]);
for(int i=2;i<=n;i++)
read(w[i]),read(x),read(v[i]),ins(x,i);
dfs(1);
for(int i=n;i;i--)
{
id=g[x=dfn[i]]+1;
for(int j=0;j<=p;j++)
{
f[i][j]=f[id][j];
if(j>=w[x])f[i][j]=max(f[i][j],f[i+1][j-w[x]]+v[x]);
}
}
for(int i=0;i<=p;i++)
ans=max(ans,f[1][i]);
write(ans);
return 0;
}