hdu 4044 2011北京赛区网络赛E 树形dp ****

专题训练

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<string.h>
  4 #include<algorithm>
  5 using namespace std;
  6 const int MAXN=1010;
  7 const int INF=0x3fffffff;
  8 struct Node
  9 {
 10     int to;
 11     int next;
 12 }edge[MAXN*2];
 13 int tol;
 14 int head[MAXN];
 15 int dp[MAXN][220];
 16 int price[MAXN][60];
 17 int power[MAXN][60];
 18 
 19 void init()
 20 {
 21     memset(head,-1,sizeof(head));
 22     tol=0;
 23 }
 24 void add(int a,int b)
 25 {
 26     edge[tol].to=b;
 27     edge[tol].next=head[a];
 28     head[a]=tol++;
 29     edge[tol].to=a;
 30     edge[tol].next=head[b];
 31     head[b]=tol++;
 32 }
 33 int n,m;
 34 int tmp[MAXN];
 35 void dfs(int u,int pre)
 36 {
 37     if(head[u]==-1||(edge[head[u]].to==pre&&edge[head[u]].next==-1))//叶子结点
 38     {//叶子结点的条件不要错了!!!!
 39         for(int i=0;i<=m;i++)dp[u][i]=0;
 40 
 41         for(int i=0;i<=m;i++)tmp[i]=dp[u][i];
 42 //因为存在价格为0的点。所以倒序的DP并不能保证只取一件物品
 43         for(int i=m;i>=0;i--)
 44         {
 45             for(int j=1;j<=price[u][0];j++)
 46                if(price[u][j]<=i)
 47                  dp[u][i]=max(dp[u][i],tmp[i-price[u][j]]+power[u][j]);
 48 
 49             tmp[i]=dp[u][i];//tmp数组是记录的dp的上一个状态
 50         }
 51         return;
 52     }
 53     for(int i=0;i<=m;i++) dp[u][i]=INF;
 54     for(int i=head[u];i!=-1;i=edge[i].next)
 55     {
 56         int v=edge[i].to;
 57         if(v==pre)continue;
 58         dfs(v,u);
 59         for(int j=m;j>=0;j--)
 60         {
 61             int t=0;
 62             for(int k=0;k<=j;k++)//这里k一定要从0开始。
 63               t=max(t,min(dp[u][j-k],dp[v][k]));
 64             dp[u][j]=t;
 65         }
 66     }
 67 
 68 
 69     for(int i=0;i<=m;i++)tmp[i]=dp[u][i];
 70     for(int i=m;i>=0;i--)
 71     {
 72         for(int j=1;j<=price[u][0];j++)
 73           if(price[u][j]<=i)
 74              dp[u][i]=max(dp[u][i],tmp[i-price[u][j]]+power[u][j]);
 75         //和上面一样分组背包加了个tmp数组
 76         tmp[i]=dp[u][i];
 77     }
 78 }
 79 int main()
 80 {
 81     int u,v;
 82     int T;
 83     scanf("%d",&T);
 84     while(T--)
 85     {
 86         init();
 87         scanf("%d",&n);
 88         for(int i=1;i<n;i++)
 89         {
 90             scanf("%d%d",&u,&v);
 91             add(u,v);
 92         }
 93         scanf("%d",&m);
 94         for(int i=1;i<=n;i++)
 95         {
 96             scanf("%d",&price[i][0]);
 97             power[i][0]=price[i][0];
 98             for(int j=1;j<=price[i][0];j++)
 99             {
100                 scanf("%d%d",&price[i][j],&power[i][j]);
101             }
102         }
103         dfs(1,0);
104         printf("%d\n",dp[1][m]);
105     }
106     return 0;
107 }

 

posted @ 2015-08-09 14:59  miao_a_miao  阅读(141)  评论(0编辑  收藏  举报