Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4340
Each node of a tree can be colored with two colors. Each color has a certain cost. A special point is that if the adjacent points have been colored with the same color, it takes only half of the price for the current color.
Last question: what is the minimum cost to dye the entire tree.
When using DP, you must first consider how to describe the status by using the constraints, because if a vertex adjacent to a vertex is dyed in the same color and all costs are required, so it takes only half of the price for the dot-dye color, so we can design such a state,
F [u] [0]: No nodes have been selected to dye the first color of U.
F [u] [1]: dye the first color of U. The nodes with full color have been selected.
G [u] [0], G [u] [1] is the second color, the state is similar
During the transfer, we can list all the obtained statuses of the subnode.
For example, F [u] [0] is required.
The sub-node statuses f [v] [0], F [v] [1], G [v] [0], and g [v] [1] have been optimized.
F [u] [0] + = min (G [v] [1], F [v] [0]), because f [u] [0] indicates that when u is the first color, it is not determined that the dot connected to U is completely colored, so it cannot be transferred from F [v] [1] to the determined status.
When F [u] [1] is obtained, either we dye the full color of the U node or a subtree of U, therefore, F [u] [1] = f [u] [0] + min (A [u], Ma );
Ma indicates the minimum value of F [v] [1]-min (G [v] [1], F [v] [0, because we need to select the f [v] [1] Status of a subtree to replace the previously added status.
Finally, add a [u]/2 to f [u] [0;
Note that if it is a leaf node, the leaf node does not have a subtree node.
#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<string>#include<set>#include<map>#include<iostream>using namespace std;const int inf = 100000;const int maxn = 101;vector<int> edge[maxn];int a[maxn],b[maxn];int f[maxn][2],g[maxn][2];void dfs(int u,int fa){ f[u][0]=0; g[u][0]=0; int sz=edge[u].size(); int m1=inf,m2=inf; bool leaf=true; for(int i=0;i<sz;i++) { int v=edge[u][i]; if(v==fa) continue; dfs(v,u); leaf=false; int tmp=min(f[v][0],g[v][1]); f[u][0]+=tmp; m1=min(m1,f[v][1]-tmp); tmp=min(g[v][0],f[v][1]); g[u][0]+=tmp; m2=min(m2,g[v][1]-tmp); } if(leaf) { f[u][1]=a[u]; f[u][0]=a[u]/2; g[u][1]=b[u]; g[u][0]=b[u]/2; } else { //printf("m1=%d\n",m1); //printf("f[u][0]=%d\n",f[u][0]); f[u][1]=f[u][0] + min(a[u],m1+a[u]/2); f[u][0]+=a[u]/2; //printf("%d %d\n\n",f[u][0],f[u][1]); g[u][1]=g[u][0] + min(b[u],m2+b[u]/2); g[u][0]+=b[u]/2; //printf("u=%d bu=%d %d %d\n",u,b[u],g[u][0],g[u][1]); }}int main(){ int n; while(scanf("%d",&n)!=EOF) { for(int i=0;i<=n;i++) edge[i].clear(); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&b[i]); for(int i=1,u,v;i<n;i++) { scanf("%d%d",&u,&v); edge[u].push_back(v); edge[v].push_back(u); } dfs(1,0); printf("%d\n",min(f[1][1],g[1][1])); } return 0;}