Very good also very annoying a tree-shaped DP, yesterday did a night is in think not out, later no way to see the solution, finished found very touching is, I started to set the state are wrong, and then has been wrong, fortunately in time rebuild.
No nonsense, the point:
The main topic: to a tree, n nodes, each node has a weight, required from the node 1 to go up to the K-step, the weight of the points passing through the maximum value, each point after a time to become 0;
Recently done some tree DP also small summed up the point of law, tree DP is generally set DP[RT][J] that is, RT as the root of the subtree J state. This problem can be set
Dp[rt][j][0] indicates that the sub-tree with RT as the root goes J-step and finally does not return to RT's solution
DP[RT][J][1] indicates that the sub-tree with RT as the root goes J-step and finally goes back to RT's solution
Equation See Code
Then for each son node to carry out a backpack, backpack capacity for steps, see a half-day problem has been feeling the equation is not right, and later saw is a backpack, (personal for the backpack is a description is put and not put the problem), think of a moment suddenly
1#include <cstdio>2#include <cstring>3#include <cstdlib>4#include <iostream>5#include <algorithm>6#include <vector>7#include <cmath>8#include <map>9 #defineINF 0x3f3f3f3fTen typedef __int64 LL; One Const intMAXN = the; A Const intMAXV = About; - using namespacestd; - intdp[maxn][maxv][2],A[MAXN]; thevector<int>SON[MAXN]; -vector<int>F[MAXN]; - BOOLVIS[MAXN]; - intn,m; + voidBuild_tree (intRT) - { + //a way of doing something more personal. A //First Use the auxiliary vector F to record the total number of edges, and then start the DFS from the root node at //find the side that is connected to RT so that it becomes the child node of RT, and then the VIS marks that edge already belongs to the child node - //can no longer be a child node of another node - //the elements in the last son[rt] are child nodes of RT - //in this way, it is still not very likely to use the adjacent table slag to find excuses for themselves. - intLen =f[rt].size (), X; - for(inti =0; i<len;++i)if(!vis[x =F[rt][i]]) { in son[rt].push_back (x); -VIS[X] =1; to build_tree (x); + } - } the voidInit () * { $memset (Vis,0,sizeof(Vis));Panax NotoginsengMemset (son,0,sizeof(son)); -Memset (F,0,sizeof(f)); the for(inti =1; i<=n;++i) scanf ("%d", A +i); + for(inti =1; i<n;++i) A { the ints,t; +scanf"%d%d",&s,&t); - F[s].push_back (t); $ F[t].push_back (s); $ } - for(inti =1; i<=n;++i) - for(intj =0; j<=m;++j) thedp[i][j][0] = dp[i][j][1] =A[i]; -vis[1] =1;WuyiBuild_tree (1); the } - voidDfsintRT) Wu { - intLen =son[rt].size (); About for(inti =0; i<len;++i) { $ intU =Son[rt][i]; - dfs (u); - for(intj = m;j>=0;--j) { - for(intK =0; k<=j;++k) { A //from RT to u finally back to RT because also to return to RT so rt->u and U->rt these two steps to exclude + if(K-2>=0) dp[rt][j][1] = max (dp[rt][j][1],dp[rt][j-k][1]+dp[u][k-2][1]); the //from RT to u end not come back is the k-1 size of items into the backpack (k-1 because rt->u excluded) - if(K-1>=0) dp[rt][j][0] = max (dp[rt][j][0],dp[rt][j-k][1]+dp[u][k-1][0]); $ //from RT to u and back to the other son's node. the if(K-2>=0) dp[rt][j][0] = max (dp[rt][j][0],dp[rt][j-k][0]+dp[u][k-2][1]); the } the } the } - } in intMain () the { the //freopen ("In.txt", "R", stdin); About while(cin>>n>>m) the { the init (); theDfs1); +Cout<<max (dp[1][m][0],dp[1][m][0]) <<Endl; - } the return 0;Bayi}
POJ 2486 Apple Tree