Topic link: https: //vjudge.net/problem/POJ-2486
Meaning of the questions: a tree right point, the starting point 1, after seeking the right to up to a maximum point and m edges.
Ideas:
Tree dp classic title. With 3-dimensional state, dp [u] [j] [0/1] represents the maximum value j take steps in the sub-tree u (back u / do not return to u). Obviously dp [u] [j] [1]> = dp [u] [j] [0], so dp [1] [m] [1] is the final answer.
Suppose v is a child node of u, k and v is the number of steps in the v as used, the transfer equation in three steps, as follows:
dp[u][j][0]=max(dp[u][j][0] , dp[u][j-k][0]+dp[v][k-2][0]) (k>=2)
dp[u][j][1]=max(dp[u][j][1] , dp[u][j-k][0]+dp[v][k-1][1]) (k>=1)
dp [u] [j] [1] = max (dp [u] [j] [1], dp [u] [jk] [1] + dp [v] [k-2] [0]) (k > = 2) (step 3 easy to forget)
AC Code:
#include<cstdio> #include<algorithm> using namespace std; const int maxn=105; const int maxm=205; int n,m,cnt,a[maxn],head[maxn],dp[maxn][maxm][2]; struct node{ int v,nex; }edge[maxn<<1]; void adde(int u,int v){ edge[++cnt].v=v; edge[cnt].nex=head[u]; head[u]=cnt; } void dfs(int u,int fa){ for(int i=head[u];i;i=edge[i].nex){ int v=edge[i].v; if(v==fa) continue; dfs(v,u); for(int j=m;j>=1;--j) for(int k=1;k<=j;++k){ if(k>=2) dp[u][j][0]=max(dp[u][j][0],dp[u][j-k][0]+dp[v][k-2][0]); if(k>=1) dp[u][j][1]=max(dp[u][j][1],dp[u][j-k][0]+dp[v][k-1][1]); if(k>=2) dp[u][j][1]=max(dp[u][j][1],dp[u][j-k][1]+dp[v][k-2][0]); } } } int main(){ while(~scanf("%d%d",&n,&m)){ cnt=0; for(int i=1;i<=n;++i) scanf("%d",&a[i]); for(int i=1;i<=n;++i){ head[i]=0; for(int j=0;j<=m;++j) dp[i][j][0]=dp[i][j][1]=a[i]; } for(int i=1;i<n;++i){ int u,v; scanf("%d%d",&u,&v); adde(u,v); adde(v,u); } dfs(1,0); printf("%d\n",dp[1][m][1]); } return 0; }