树形背包

 一棵树,每个节点都有权值,问必须包含根节点的权值和最大的联通块,联通快大小为k,求权值和 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 2510
#define eps 0.00001
using namespace std;
int K,n,m,head[maxn],num,sz[maxn];
double w[maxn],f[maxn][maxn];
struct node{int to,pre;}e[maxn*2];
void Insert(int from,int to){
    e[++num].to=to;
    e[num].pre=head[from];
    head[from]=num;
}
void dfs(int x){
    sz[x]=1;
    for(int i=head[x];i;i=e[i].pre){
        int to=e[i].to;
        dfs(to);
        sz[x]+=sz[to];
    }
}
void dp(int x){
    int tot;
    f[x][1]=w[x],tot=1;
    for(int i=head[x];i;i=e[i].pre){
        int to=e[i].to;
        dp(to);
        tot+=sz[to];
        for(int j=tot;j>=0;j--)
            for(int k=min(sz[to],j);k>=0;k--)
                f[x][j]=max(f[x][j],f[x][j-k]+f[to][k]);
    }
}
int main(){
    scanf("%d",&n);
    int x,y;
    for(int i=1;i<=n;i++)scanf("%lf",&w[i]);
    for(int i=1;i<n;i++){
        scanf("%d%d",&x,&y);
        Insert(x,y);
    }
    dfs(1);
    memset(f,0xc2,sizeof(f));
    dp(1);
    printf("%lf",f[1][2]);
    return 0;
}
原文地址:https://www.cnblogs.com/thmyl/p/8872883.html