POJ 1155 TELE tree backpack, pojtele
Link: http://poj.org/problem? Id = 1155
A TV station broadcasts an important football match. It uses this broadcasting machine as the root to establish a "broadcasting tree". There are N in total (N <= 3000 ), leaf nodes are all users, with M users (M <= N-1), each user has a fixed amount of paid. Except for users, all nodes are machine for signal transfer, and there is a certain cost for connecting all nodes. Now, I want to meet the viewing requirements of more people as much as possible, and ensure that the broadcast will not lose money. Ask the maximum number of viewers that can be guaranteed.
Train of Thought: record the number of viewing requests that can be met by the current node from the leaf to the root, and record the maximum benefit that meets this number, that is, perform a backpack DP for each node, ensures the optimization of each decision.
State transition equation: dp [u] [j] = max (dp [u] [j], dp [v] [k] + dp [u] [j-k]-w), u is the current node, v is the subnode, j is a satisfying number of people in u, k is a satisfying number from v, and dp [v] [k] has been determined first. W is the cost of the path. For each leaf node dp [u] [1], it is the cost that u can pay.
Code:
#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <ctype.h>#include <iostream>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <vector>#define eps 1e-8#define INF 0x3fffffff#define maxn 3005#define PI acos(-1.0)#define seed 31//131,1313typedef long long LL;typedef unsigned long long ULL;using namespace std;int head[maxn],top,dp[maxn][maxn],t[maxn],N,M,tot,x,y,num[maxn];void init(){ memset(head,-1,sizeof(head)); for(int i=1; i<=N; i++) for(int j=1; j<=N; j++) dp[i][j]=-INF; memset(t,0,sizeof(t)); memset(num,0,sizeof(num)); top=0;}struct Edge{ int v,w; int next;} edge[maxn];void add_edge(int u,int v,int w){ edge[top].v=v; edge[top].w=w; edge[top].next=head[u]; head[u]=top++;}void dfs(int u,int f){ for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v,w=edge[i].w; if(v!=f) { dfs(v,u); num[u]+=num[v]; for(int j=num[u]; j>=1; j--) for(int k=1; k<=min(j,num[v]); k++) if(dp[v][k]!=-INF) dp[u][j]=max(dp[u][j],dp[v][k]+dp[u][j-k]-w); } }}int main(){ scanf("%d%d",&N,&M); init(); for(int i=1; i<=N-M; i++) { scanf("%d",&tot); for(int j=1; j<=tot; j++) { scanf("%d%d",&x,&y); add_edge(i,x,y); } } for(int i=N-M+1; i<=N; i++) { scanf("%d",&dp[i][1]); num[i]=1; } dfs(1,1); for(int i=num[1]; i>=0; i--) if(dp[1][i]>=0) { printf("%d\n",i); break; } return 0;}