树上背包,如果选择子树父节点必须选,所以边界初始化要注意一下。具体分析待整理。
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 ", 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++ |