二叉苹果树
这是一个树形dp入门题。
f[x][i]=max{f[lc[x]][i-1]+lw[x],f[rc[x]][i-1]+rw[x],lw[x]+rw[x]+f[lc[x]][j]+f[rc[x]][i-2-j]}
注意边界情况。
if(i==0)f[x][i]=0; if(!lc[x])f[x][i]=0;
那么这就是代码:
#include<bits/stdc++.h> using namespace std; const int maxn=1000; int f[maxn][maxn]; int n,m,vis[maxn],fa[maxn],lc[maxn],rc[maxn],lw[maxn],rw[maxn]; int beg[maxn],nex[maxn],to[maxn],w[maxn],e; inline void add(int x,int y,int z){ e++;nex[e]=beg[x]; beg[x]=e;to[e]=y;w[e]=z; } inline void build(int x,int anc){ fa[x]=anc; for(int i=beg[x];i;i=nex[i]) if(to[i]!=anc){ build(to[i],x); if(lc[x])rc[x]=to[i],rw[x]=w[i]; else lc[x]=to[i],lw[x]=w[i]; } } inline int dfs(int x,int ed){ if(ed==0||!lc[x])return 0; if(f[x][ed])return f[x][ed]; f[x][ed]=max(f[x][ed],lw[x]+dfs(lc[x],ed-1)); f[x][ed]=max(f[x][ed],rw[x]+dfs(rc[x],ed-1)); for(int i=0;i<=ed-2;i++) f[x][ed]=max(f[x][ed],lw[x]+rw[x]+dfs(lc[x],i)+dfs(rc[x],ed-2-i)); //printf("f[%d][%d]=%d\n",x,ed,f[x][ed]); return f[x][ed]; } int main(){ cin>>n>>m; int x,y,z; for(int i=1;i<n;i++){ scanf("%d%d%d",&x,&y,&z); add(x,y,z),add(y,x,z); } build(1,0); printf("%d\n",dfs(1,m)); return 0; }
深深地感到自己的弱小。