The topic is to say to a tree, the leaf knot has the negative right, the side has the right, the question can choose how many leaves node, make from leaves to the root of the weight and less than equal to 0.
Consider the size of the data to indicate the state: Dp[u][k] indicates that the minimum weight of K leaf nodes is selected in a subtree of the root of the U node.
Finally, find the largest k that satisfies from d[1][k]. However, the transfer time complexity is the number of points, it is obvious that the problem is to use a tree backpack.
But in fact, the complexity of the time is not counted = = Anyway, it feels quite reliable, hand over AC.
and made a tree backpack, HDU1561 and POJ3345.
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5 #defineINF (1<<29)6 #defineMAXN 30017 structedge{8 intU,v,w,next;9 }EDGE[MAXN];Ten intNE,HEAD[MAXN]; One voidAddedge (intUintVintW) { AEdge[ne].u=u; Edge[ne].v=v; edge[ne].w=W; -Edge[ne].next=head[u]; head[u]=ne++; - } the - intD[MAXN][MAXN],SIZE[MAXN]; - voidDfsintu) { - BOOLisleaf=1; + for(intI=head[u]; i!=-1; I=Edge[i].next) { - intv=edge[i].v; + Dfs (v); Asize[u]+=Size[v]; atisleaf=0; - } - if(isleaf) size[u]=1; - } - intVAL[MAXN]; - voiddpintu) { in BOOLisleaf=1; - for(intI=head[u]; i!=-1; I=Edge[i].next) { to intv=edge[i].v; + DP (v); -isleaf=0; the for(intJ=size[u]; j>=1; --j) { * for(intk=1; K<=min (J,size[v]); ++k) D[u][j]=min (d[u][j],d[u][j-k]+d[v][k]+EDGE[I].W); $ }Panax Notoginseng } - if(isleaf) d[u][1]=-Val[u]; the } + intMain () { Amemset (head,-1,sizeof(head)); the intn,m,k,a,b; +scanf"%d%d",&n,&m); - for(intI=1; i<=n; ++i) { $ for(intj=1; j<=m; ++J) d[i][j]=INF; $ } - for(intI=1; i<=n-m; ++i) { -scanf"%d",&k); the while(k--){ -scanf"%d%d",&a,&b);Wuyi Addedge (i,a,b); the } - } Wu for(inti=n-m+1; i<=n; ++i) { -scanf"%d", val+i); About } $Dfs1); -dp1); - for(intI=m; i>=0; --i) { - if(d[1][i]<=0){ Aprintf"%d", i); + Break; the } - } $ return 0; the}
POJ1155 TELE (tree-shaped DP)