题目链接:http://poj.org/problem?id=1155
题目大意:电视台要广播电视节目,要经过中转机构,到观众。从电视台到中转商到观众是一个树形结构,经过一条边需要支付成本。现在给你每两个节点之间传播的成本,给你每个观众会付的钱,问你电视台在不亏本的情况下最多能给多少个观众看节目。
这是我的第一道树形dp。。无耻的看了题解。。
设计状态:dp[u][i]代表以u为根的子树中有i个观众,能够得到的最大收入。
状态转移:dp[u][i] = max(dp[u][i],dp[u][i-j]+dp[v][j]-cost[u][v]);
用java写了一个版本。。总是RE,就不知道是为什么了。。
代码:
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 using namespace std; 7 8 const int MAX_N = 3333; 9 const int INF = 99999999; 10 struct EDGE{ 11 int to,cost; 12 int next; 13 }; 14 EDGE edge[MAX_N<<1]; 15 int ptr,head[MAX_N]; 16 int cost[MAX_N]; 17 18 void init(){ 19 memset(edge,-1,sizeof(edge)); 20 memset(head,-1,sizeof(head)); 21 ptr = 0; 22 } 23 24 void add_edge(int from,int to,int cost){ 25 edge[ptr].to = to; 26 edge[ptr].cost = cost; 27 edge[ptr].next = head[from]; 28 head[from] = ptr++; 29 } 30 31 int N,M; 32 int dp[MAX_N][MAX_N]; 33 bool vis[MAX_N]; 34 int sum[MAX_N]; 35 36 void DP(int u){ 37 if( vis[u] ) return; 38 vis[u] = true; dp[u][0] = 0; 39 int tot = 0; 40 41 for(int i=head[u];~i;i=edge[i].next){ 42 int v = edge[i].to; 43 if( !vis[v] ){ 44 tot++; 45 DP( v ); 46 sum[u] += sum[v]; 47 } 48 } 49 50 if( tot==0 ){ 51 sum[u] = 1; 52 dp[u][1] = cost[u]; 53 } else { 54 for(int k=head[u];~k;k=edge[k].next){ 55 int v = edge[k].to; 56 for(int j=sum[u];j>=1;--j){ 57 for(int i=1;i<=sum[v];i++){ 58 if( j>=i && dp[u][j-i]!=-INF && dp[v][i]!=-INF){ 59 dp[u][j] = max(dp[u][j],dp[u][j-i]+dp[v][i]-edge[k].cost); 60 } 61 } 62 } 63 } 64 } 65 } 66 67 int main(){ 68 while(scanf("%d%d",&N,&M)!=EOF){ 69 init(); 70 int k; 71 for(int i=1;i<=N-M;i++){ 72 scanf("%d",&k); 73 for(int j=0;j<k;j++){ 74 int a,c; 75 scanf("%d%d",&a,&c); 76 add_edge(i,a,c); 77 add_edge(a,i,c); 78 } 79 } 80 81 for(int i=N-M+1;i<=N;i++){ 82 scanf("%d",&cost[i]); 83 } 84 85 memset(vis,0,sizeof(vis)); 86 memset(sum,0,sizeof(sum)); 87 for(int i=0;i<=N;i++){ 88 for(int j=0;j<=N;j++){ 89 dp[i][j] = -INF; 90 } 91 } 92 DP(1); 93 for(int i=N;i>=0;--i){ 94 if( dp[1][i] >=0 ) { 95 printf("%d\n",i); 96 break; 97 } 98 } 99 100 } 101 return 0; 102 }
时间: 2024-11-05 19:34:15