The system of television, transit, and user's TV is just a tree.
n nodes, numbered respectively 1~n,1 is the TV station Center, 2~n-m is the broker, N-m+1~n is the user, 1 is the root
Now node 1 ready to broadcast a game, known to transfer data from one node to another node, the TV station needs a certain cost
If the data can be transferred to the user's node n-m+1~n, these users are willing to pay a certain fee to the TV station
Now the TV station wants to broadcast the competition for as many users as possible without losing money.
Output up to how many users broadcast the game
Tree DP first question of backpack type
DP[I][J] indicates that a subtree with node i is the root of a tree with J users receiving retransmission, the maximum benefit of the TV station
Since there is a positive negative income
Initialization
Dp[i][0]=0
Dp[i][j]=-inf (j>0)
Target: Dp[1][j]>=0 under the condition of the largest J
(Dp[1][j]>=0 said the TV station does not lose money)
Process of Dfs recursive DP
There's an idea where the notes are written.
1#include <cstdio>2#include <cstring>3 4 using namespacestd;5 6InlineintMaxintAintb)7 {8 returnA>b?a:b;9 }Ten One Const intmaxn=3005; A Const intinf=0x3f3f3f3f; - - intDP[MAXN][MAXN]; the intCOST[MAXN][MAXN]; - intSIZ[MAXN]; - structEdge - { + intTo,next; - }; + Edge EDGE[MAXN]; A intHEAD[MAXN]; at inttot; - intn,m; - - voidAddedge (intUintv) - { -edge[tot].to=v; inedge[tot].next=Head[u]; -head[u]=tot++; to } + - voidInit () the { *memset (head,-1,sizeofhead); $tot=0;Panax Notoginseng for(intI=1; i<=n;i++) - { thedp[i][0]=0; + for(intj=1; j<=m;j++) Adp[i][j]=-inf; the } + } - $ voidsolve (); $ voidDfsintu); - - intMain () the { - while(~SCANF ("%d",&N))Wuyi { thescanf"%d",&m); - init (); Wu for(intI=1; i<=n-m;i++) - { About intnum; $scanf"%d",&num); - while(num--) - { - intu; Ascanf"%d",&u); +scanf"%d",&Cost[i][u]); the Addedge (i,u); - } $ } the for(inti=n-m+1; i<=n;i++) the { thescanf"%d", &cost[i][maxn-1]); the } - solve (); in } the return 0; the } About the voidSolve () the { theDfs1); + for(intj=siz[1];j>=0; j--) - { the if(dp[1][j]>=0)Bayi { theprintf"%d\n", j); the return ; - } - } the /* the for (int i=0;i<=siz[1];i++) the printf ("%d\n", Dp[1][i]); the */ - } the the voidDfsintu) the {94siz[u]=0; the for(intI=head[u];~i;i=edge[i].next) the { the intv=edge[i].to;98 if(n-m<v) About { -dp[v][0]=0;101dp[v][1]=cost[v][maxn-1];102siz[v]=1;103 }104 Else the {106 Dfs (v);107 }108siz[u]+=Siz[v];109 the //due to update dp[u][j]111 //Dp[u][j-k] needs to represent a subtree with the root of U, and j-k is taken from the front son node . the //so this time dp[u][j-k] can not be updated by the Son node V (to ensure that j-k are taken from the front)113 //So, when the recursion is pushed, J pushes the inverse . the //Of course, the order of the K and J loops cannot be exchanged. the for(intJ=siz[u];j>0; j--) the {117 for(intk=1; k<=siz[v];k++)118 if(j>=k)119Dp[u][j]=max (dp[u][j],dp[u][j-k]+dp[v][k]-cost[u][v]); - }121 }122}
View Code
POJ 1155 TELE Backpack type Tree DP Classic