POJ 1947

树上背包,主要是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
", 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
原文地址:https://www.cnblogs.com/e0e1e/p/poj_1947.html