Test instructions: There are N points, N-1 Edge, any two points can reach, thus forming a tree. Select a point a, which can cover itself and the point adjacent to itself, select as few points a as possible, so that the tree is a bit covered, that is, the minimum point of the tree to dominate the set.
Analysis:
1, for each point cur, want to make it covered, there are three kinds of situations:
DP[CUR][0]---Build a tower at that point
DP[CUR][1]---Build towers at the sub-nodes of the point
DP[CUR][2]---Set up a tower at that point's parent node.
2, for the point cur of the sub-node x, to make it covered:
(1) dp[cur][0] + = min (min (dp[x][0], dp[x][1]), dp[x][2]);
In the case of Cur tower, X can be built tower, x child nodes can be built tower, X's parent node is cur Tower, the three take the minimum value, and accumulate.
(2) dp[cur][2] + = Min (Dp[x][0], dp[x][1]);
In the case of the Cur's parent node tower, X can be built, and X's sub-nodes can be built, both of which take the minimum value and accumulate.
(3) dp[cur][1] + = Min (Dp[x][0], dp[x][1]);
In the case of Cur's sub-node tower, at least one sub-node of the cur must be built cur to be overwritten, so for each sub-node x,x can be built tower, x sub-nodes can be built tower, both take the minimum value
At the same time, the record in the case of minimum value, cur whether there is a sub-node can build the tower, if not, you need to cur a sub-node into a tower, choose ABS (Dp[x][1]-dp[x][0]) the smallest sub-node x changes can be.
3, dp[cur][0] finally add 1 because the tower is to be built at the cur point.
#pragma COMMENT (linker, "/stack:102400000, 102400000") #include <cstdio> #include <cstring> #include < cstdlib> #include <cctype> #include <cmath> #include <iostream> #include <sstream> #include <iterator> #include <algorithm> #include <string> #include <vector> #include <set># include<map> #include <stack> #include <deque> #include <queue> #include <list> #define Min (A, B) ((a < b) a:b) #define MAX (A, B) ((a < b) b:a) const DOUBLE EPS = 1e-8;inline int dcmp (double A, Doub Le b) {if (Fabs (a) < EPS) return 0; Return a > B? 1:-1;} typedef long Long Ll;typedef unsigned long long ull;const int int_inf = 0x3f3f3f3f;const int int_m_inf = 0x7f7f7f7f;const ll ll_inf = 0x3f3f3f3f3f3f3f3f;const LL ll_m_inf = 0x7f7f7f7f7f7f7f7f;const int dr[] = {0, 0,-1, 1,-1,-1, 1, 1};const I NT Dc[] = {-1, 1, 0, 0,-1, 1,-1, 1};const int MOD = 1e9 + 7;const Double pi = ACOs ( -1.0); const int MAXN = 10000 + 10;con St INT MAXT = 10000 + 10;using namespace std;int n;vector<int> v[maxn];int dp[maxn][5];void dfs (int cur, int father) { memset (Dp[cur], 0, sizeof dp[cur]); int len = V[cur].size (); int dif = Int_inf; bool OK = false; for (int i = 0; i < len; ++i) {int x = v[cur][i]; if (x = = father) Continue; if (dp[x][0] = = Int_inf) dfs (x, cur); Dp[cur][0] + = min (min (dp[x][0], dp[x][1]), dp[x][2]); DP[CUR][2] + = Min (Dp[x][0], dp[x][1]); dif = Min (DIF, ABS (dp[x][1]-dp[x][0)); if (Dp[x][0] < dp[x][1]) {OK = true; DP[CUR][1] + = dp[x][0]; } else{dp[cur][1] + = dp[x][1]; }} ++dp[cur][0]; if (!ok) dp[cur][1] + = dif;} int main () {scanf ("%d", &n); for (int i = 0; i < N-1; ++i) {int A, B; scanf ("%d%d", &a, &b); V[a].push_back (b); V[b].push_back (a); } memset (DP, Int_inf, sizeof DP); DFS (1,-1); printf ("%d\n", Min (dp[1][0), dp[1][1])); return 0;}
POJ-3659 Cell Phone Network (minimum point domination set for tree DP---tree)