码迷,mamicode.com
首页 > 其他好文 > 详细

[POJ 1155] TELE (树形dp)

时间:2014-10-29 16:45:48      阅读:394      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   color   os   ar   java   for   

题目链接: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 }

 

[POJ 1155] TELE (树形dp)

标签:style   blog   http   io   color   os   ar   java   for   

原文地址:http://www.cnblogs.com/llkpersonal/p/4059768.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!