这也是道树形的背包,很恶心。以至于我都不想解释了。。。都在程序里。
//By YY_More #include<cstdio> #include<cstring> struct edge{ int point; edge *next; }; int N,K,a,b,W[201],F[101][201],H[101][201]; bool ed[101]; edge *g[101]; void insert(int from,int to){ edge *p=new edge; (*p).next=g[from]; g[from]=p; (*p).point=to; } void dp(int x){ ed[x]=true; edge *p=g[x]; while (p!=NULL){ if (!ed[(*p).point]){ dp((*p).point); for (int i=K;i>=2;i--) for (int j=0;j<=i-2;j+=2) if (F[(*p).point][j]+H[x][i-j-2]>H[x][i]) H[x][i]=F[(*p).point][j]+H[x][i-j-2]; for (int i=K;i>=1;i--) for (int j=0;j<i;j+=2) if (F[x][j]+H[(*p).point][i-j-1]>H[x][i]) H[x][i]=F[x][j]+H[(*p).point][i-j-1]; for (int i=(K/2)*2;i>=2;i-=2) for (int j=0;j<=i-2;j+=2) if (F[x][j]+F[(*p).point][i-j-2]>F[x][i]) F[x][i]=F[x][j]+F[(*p).point][i-j-2]; } p=(*p).next; } for (int i=0;i<=K;i+=2) F[x][i]+=W[x]; for (int i=0;i<=K;i++) H[x][i]+=W[x]; } int main(){ while (~scanf("%d%d",&N,&K)){ memset(ed,0,sizeof(ed)); memset(g,0,sizeof(g)); for (int i=1;i<=N;i++) scanf("%d",&W[i]); for (int i=1;i<N;i++){ scanf("%d%d",&a,&b); insert(a,b); insert(b,a); } memset(F,0,sizeof(F)); memset(H,0,sizeof(H)); dp(1); printf("%d\n",H[1][K]); } return 0; }