POJ 1947 - Rebuilding Roads
树上背包,主要是treedp还是不熟卡了几天。待整理。
#include <cstdio> #include <cstring> using namespace std; #define MAXV 155 #define MAXE (MAXV - 1) int Vefw[MAXE], Vet[MAXE], Veh[MAXV], Veptr; #define addedge(s, t) ({\ Vefw[Veptr] = Veh[s], Vet[Veptr] = t; \ Veh[s] = ++Veptr; }) int N, P; int dp[MAXV][MAXV+1]; int ans; int solve(int o, int s) { int nsum; for(int i = N-1; i > 1; --i) dp[s][i] = N-1; dp[s][nsum = 1] = 0; for(int e = Veh[s]; e; e = Vefw[e]) { int t = Vet[--e]; int tsum = solve(1, t); for(int i = nsum + tsum; i>0; --i) { dp[s][i] = dp[s][i] + 1; for(int j=1; j<=tsum ; ++j) { if (i - j <= 0) break; if (dp[s][i] > dp[s][i-j] + dp[t][j]) dp[s][i] = dp[s][i-j] + dp[t][j]; } } nsum += tsum; } if (ans > dp[s][P] + o) ans = dp[s][P] + o; return nsum; } int main(void) { // freopen("poj1947.txt", "r", stdin); scanf("%d%d", &N, &P); ans = N-1; int root = 0; for(int i=1; i<N; ++i) { int s, t; scanf("%d%d", &s, &t); --s, --t; addedge(s,t); if (root == t) root = s; } solve(0, root); printf("%d\n", ans); return 0; }
1947 | Accepted | 476K | 16MS | G++ | 1111B | 2014-05-14 11:57:45 |
1947 | Accepted | 476K | 32MS | G++ | 1092B | 2014-05-14 11:43:47 |
This article is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
本文采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。