Backpack is a simple DP, so it's not easy to put it on a tree.
Tree Backpack Primary Practice:
Suppose f[i][j] is rooted in I node and the volume is the maximum benefit of I. In fact, f[u][i][j] means taking u as the root and selecting I subtrees, the volume of which is the maximum benefit of J. However, through the one-dimensional inverted cycle of volume (like 01 knapsack), it can be optimized to O (n^2) in space, but in time, it is still very large, O(n^3).
F [i] [j] = max (f [i] [j], f [i] [j], f [i] [j-k] + F [v] [k]) (cyclic J inversion, K from 0 to j.)
The answer is f [root] [knapsack volume]
Then there is optimization:
Let f[i][j] denote that the dfs order is from I to tot, and the volume is the maximum value of J.
The siz of each subtree is calculated once by dfs, and the mapping of each DFS sequence to the original number is established. (id[++num]=x).
F [i] [j] = max (f [i + siz [i]] [j], f [i + 1] [j-w [i] + val [i]) (cyclic I inversion)
The answer is f[1] [knapsack volume]
There are other optimizations, but I won't...
The following is the code:
Examples Luogu P2515 [HAOI2010] Software Installation
simple1 #include<bits/stdc++.h> 2 #define ll long long 3 #define RE register 4 using namespace std; 5 const int maxn=2200; 6 inline int R(){ 7 RE char b=getchar();int x=0,t=1; 8 while(b<'0'||b>'9'){if(b=='-') t=-1;b=getchar();} 9 while(b>='0'&&b<='9') {x=(x<<3)+(x<<1)+b-'0';b=getchar();} 10 return x*t; 11 } 12 struct Edge{ 13 int nxt,to; 14 }ed[maxn]; 15 int head[maxn],ecnt; 16 void addedge(int f,int to){ 17 ed[++ecnt].to=to; 18 ed[ecnt].nxt=head[f]; 19 head[f]=ecnt; 20 } 21 int n,m; 22 int w[maxn],v[maxn],d[maxn]; 23 int ww[maxn],vv[maxn],rd[maxn]; 24 int siz[maxn]; 25 int f[maxn][maxn]; 26 void dfs(int x){// Focusing 27 for(int i=ww[x];i<=m;i++) f[x][i]=vv[x]; 28 // f[x][ww[x]]=vv[x]; 29 for(int i=head[x];i;i=ed[i].nxt){ 30 int v=ed[i].to; 31 dfs(v); 32 for(int j=m-ww[x];j>=0;j--) for(int k=0;k<=j;k++){ 33 f[x][j+ww[x]]=max(f[x][j+ww[x]],f[x][j+ww[x]-k]+f[v][k]); 34 } 35 } 36 } 37 int dfn[maxn],low[maxn],num; 38 bool vis[maxn]; 39 int sta[maxn],tp; 40 int scc_num,scc[maxn]; 41 void tarjan(int x){ 42 sta[++tp]=x; 43 vis[x]=1; 44 dfn[x]=low[x]=++num; 45 for(int i=head[x];i;i=ed[i].nxt){ 46 int v=ed[i].to; 47 if(!dfn[v]){ 48 tarjan(v); 49 low[x]=min(low[x],low[v]); 50 } 51 else if(vis[v]) low[x]=min(low[x],dfn[v]); 52 } 53 if(low[x]==dfn[x]){ 54 scc_num++; 55 int tmp; 56 do{ 57 tmp=sta[tp--]; 58 vis[tmp]=0; 59 scc[tmp]=scc_num; 60 ww[scc_num]+=w[tmp]; 61 vv[scc_num]+=v[tmp]; 62 }while(tmp!=x); 63 } 64 } 65 int main(){ 66 n=R(),m=R(); 67 for(int i=1;i<=n;i++) w[i]=R(); 68 for(int i=1;i<=n;i++) v[i]=R(); 69 for(int i=1;i<=n;i++){ 70 d[i]=R(); 71 if(d[i]) addedge(d[i],i); 72 } 73 for(int i=1;i<=n;i++){ 74 if(!dfn[i]) tarjan(i); 75 } 76 memset(head,0,sizeof head); 77 memset(ed,0,sizeof ed);ecnt=0; 78 for(int i=1;i<=n;i++){ 79 int f=d[i],to=i; 80 if(scc[f]!=scc[to]&&f) addedge(scc[f],scc[to]),rd[scc[to]]++; 81 } 82 for(int i=1;i<=scc_num;i++) 83 if(!rd[i]) addedge(scc_num+1,i);//Must first shrink point and super source point, otherwise the ring will not be connected to super source point. 84 dfs(scc_num+1); 85 printf("%d\n",f[scc_num+1][m]); 86 return 0; 87 }