# bzoj 1017 tree dp

  1 /**************************************************************
2     Problem: 1017
3     User: idy002
4     Language: C++
5     Result: Accepted
6     Time:16524 ms
7     Memory:48316 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <cstring>
12 #include <vector>
13 #define max(a,b) ((a)>(b)?(a):(b))
14 #define min(a,b) ((a)<(b)?(a):(b))
15 #define maxn 55
16 #define maxm 2010
17 #define maxl 110
18 #define oo 0x3f3f3f3f
19 using namespace std;
20
21
22 int n, m;
23 int indgr[maxn];
24 int power[maxn], cost[maxn], limit[maxn];
25 int head[maxn], next[maxn], dest[maxn], wght[maxn], tot;
26
27 int dp[maxn][maxm][maxl];
28 int ep[maxm];
29
30 void insert( int a, int b, int w ) {
31     tot++;
32     wght[tot] = w;
33     dest[tot] = b;
36 }
37 void dfs( int i ) {
39     cost[i] = 0;
40     limit[i] = oo;
41
42     for( int t=head[i]; t; t=next[t] ) {
43         int s = dest[t], w = wght[t];
44         dfs( s );
45         cost[i] += cost[s]*w;
46         limit[i] = min( limit[i], limit[s]/w );
47     }
48 }
49
50
51 void dodp( int i ) {
53         for( int l=0; l<=limit[i]; l++ )
54             for( int k=l; k>=0; k-- ) {
55                 int self = (l-k);
56                 int j = self*cost[i];
57                 if( j>m ) break;
58                 dp[i][j][k] = self*power[i];
59             }
60         return;
61     }
62     for( int t=head[i]; t; t=next[t] )
63         dodp( dest[t] );
64     for( int l=0; l<=limit[i]; l++ ) {
65         for( int j=0; j<=m; j++ ) ep[j]=0;
66         for( int t=head[i]; t; t=next[t] ) {
67             int v = dest[t], w = wght[t];
68             int vl = l*w;
69             for( int j=m; j>=0; j-- )
70                 for( int jj=0; jj<=j; jj++ )
71                     ep[j] = max( ep[j], ep[j-jj]+dp[v][jj][vl] );
72         }
73         for( int j=0; j<=m; j++ )
74             for( int k=l; k>=0; k-- ) {
75                 int self = l-k;
76                 int remain =  j- self*cost[i];
77                 if( remain<0 ) break;
78                 dp[i][j][k] = max( dp[i][j][k], ep[remain]+self*power[i] );
79             }
80     }
81 }
82
83 int main() {
84     scanf( "%d%d", &n, &m );
85     for( int i=1; i<=n; i++ ) {
86         char type[10];
87         scanf( "%d%s", power+i, type );
88         if( type[0]=='A' ) {
89             int cnt;
90             scanf( "%d", &cnt );
91             for( int t=1,c,w; t<=cnt; t++ ) {
92                 scanf( "%d%d", &c, &w );
93                 insert( i, c, w );
94                 indgr[c]++;
95             }
96         } else
97             scanf( "%d%d", cost+i, limit+i );
98     }
99     int root = 0;
100     for( int i=1; i<=n; i++ )
101         if( indgr[i]==0 ) {
102             root = i;
103             break;
104         }
105     memset( dp, 129, sizeof(dp) );
106     dfs(root);
107     dodp(root);
108     int ans = 0;
109     for( int j=0; j<=m; j++ ) ans = max( ans, dp[root][j][0] );
110     printf( "%d\n", ans );
111 }
View Code

posted @ 2015-02-21 15:50  idy002  阅读(139)  评论(0编辑  收藏  举报