HDU 1561 - The more, The Better

树上背包,如果选择子树父节点必须选,所以边界初始化要注意一下。具体分析待整理。

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 #define MAXV    205
 6 #define MAXE    (MAXV-1)
 7 
 8 int Vefw[MAXE], Veh[MAXV], Vet[MAXE], Veptr;
 9 
10 #define addedge(s,t) ({\
11     Vefw[Veptr] = Veh[s], Vet[Veptr] = t; \
12     Veh[s] = ++Veptr; })
13 
14 int N;
15 int dp[MAXV][MAXV+1];
16 #define Vtrs(x)        dp[x][1]
17 
18 int solve(int s)
19 {
20     for(int i=N; i>1; --i)
21         dp[s][i] = 0;
22     int nsum = 1;
23 
24     for(int e = Veh[s]; e; e = Vefw[e]) {
25         int t = Vet[--e];
26         int tsum = solve(t);
27 
28         for(int i=nsum + tsum; i>0; --i) {
29             for(int j=1; j<=tsum; ++j) {
30                 if (i - j <= 0) break;
31                 if (dp[s][i] < dp[s][i-j] + dp[t][j])
32                     dp[s][i] = dp[s][i-j] + dp[t][j];
33             }
34         }
35 
36         nsum += tsum;
37     }
38     return nsum;
39 }
40 
41 int M;
42 
43 int main(void)
44 {
45     freopen("hdu1561.txt", "r", stdin);
46     while(scanf("%d%d", &N, &M), N && M) {
47         ++N, Veptr = 0;
48         for(int t=1; t<N; ++t) {
49             int s;
50             scanf("%d%d",&s, &Vtrs(t));
51             addedge(s, t);
52         }
53         solve(0);
54         printf("%d\n", dp[0][M+1]);
55         memset(Veh, 0, sizeof(int) * N);
56     }
57     return 0;
58 }

 

10738682 2014-05-14 14:41:32 Accepted 1561 0MS 372K 1040 B G++
posted @ 2014-05-14 14:52  e0e1e  阅读(122)  评论(0编辑  收藏  举报