Meaning of the questions:
Ideas:
So, we consider a node can be dyed by whom, is not difficult to come up with, there may be three cases: dyed myself, being the son of dyeing, dyed his father
We wish to set up:
f [i] [0] represents f [i] own dyeing [1] on behalf of his father dyed f [i] [2] represents staining son
Set the current node is u, v is the son node
Let's consider the transfer equation:
1 I have been dyeing their own
Then we can think about, u by their own staining can be transferred from what is to come, if u have dyed his words, his son v You can choose your own coloring, you can also choose to be their own stained son, of course, can also be u staining of course, we want to choose the smallest, so that the transfer equation
f [u] [0] + = min (f [v] [0], f [v] [1], f [v] [2])
2 by their own father node staining
If the father node ( f A) staining, then u son of v can only choose their own stained or dyed by its son, the transfer equation
f[u][1] += min(f[v][1],f[v][0] )
3 by his own son nodes stained
This is the most troublesome case, because u may have more sons, a son of their own as long as there is a stain, it can u cover, this situation is set up
And now it's the son of two cases, which are themselves dyeing and staining it was his son
We can assume that each son is dyed (its own v is its own dyed), and then look at the u of each son ( v) whether his son is dyed to make the results become smaller, to make the results less their staining ( replacing his own son v staining) is dyed their son son ( v dyed its son) son
#include <iostream> #include <algorithm> #include <string> #include <string.h> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <math.h> #include <cstdio> #include <iomanip> #include <time.h> #include <bitset> #include <cmath> #define LL long long #define INF 0x3f3f3f3f #define ls nod<<1 #define rs (nod<<1)+1 const double eps = 1e-10; const int maxn = 1e5 + 10; const LL mod = 1e9 + 7; int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} using namespace std; struct edge { int v,nxt; }e[maxn << 1]; int head[maxn]; int cnt; int f[maxn][3]; inline void add_edge(int u,int v) { e [ ++ cnt] .v = v; to [cnt] .nxt = Head [e]; head[u] = cnt; } void dfs(int u,int fa) { f[u][0] = 1; int tot = 0; int g[maxn]; for (int i = head[u];~i;i = e[i].nxt) { int v = e[i].v; if (v == fa) continue; dfs (v, u); f [u] [ 0 ] + = min (f [v] [ 0 ] [min (f [v] [ 1 ], f [v] [ 2 ])); f[u][1] += min(f[v][0],f[v][2]); f[u][2] += f[v][0]; g [ ++ tot] = f [v] [ 2 ] - f [v] [ 0 ]; } if (!tot) f[u][2] = INF; else { sort(g+1,g+1+tot); for (int i = 1;i < tot;i++) { if (g[i] < 0) f[u][2] += g[i]; else break; } } } int main () { cnt = 0; memset(head,-1, sizeof(head)); int n; cin >> n; for (int i = 1;i < n;i++) { int u,v; cin >> u >> v; add_edge(u,v); add_edge(v,u); } dfs(1,0); cout << min(f[1][0],f[1][2]) << endl; return 0; }