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.
[Cpp]
# Include <cstdio>
# Include <cstring>
# Include <iostream>
# Include <vector>
# Include <string>
# Include <set>
# Include <map>
# Include <iostream>
Using namespace std;
Constint 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 \ 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 \ 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", & 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;
}
Author: haha593572013