UV 12452 Plants vs. Zombies hd sp tree dp (water, 12452 zombies
Question link: Click the open link
Question:
Tree with given n points [0, n)
At first, all edges are colorless.
There are three types of operations:
1. Select a vertex to dye the connected edge. The cost is 100.
2. It takes 175 to select two edges connected by a dot-dye.
3. It takes 500 to select a vertex to dye all edges connected to it.
Q:
Minimum Cost of dyeing all edges. Edges can be repeatedly colored, and vertices can only be operated once.
# Include <string> # include <iostream> # include <cstdio> # include <algorithm> # include <cmath> # include <cstring> # include <queue> # include <set> # include <map> # include <vector> template <class T> inline bool rd (T & ret) {char c; int sgn; if (c = getchar (), c = EOF) return 0; while (c! = '-' & (C <'0' | c> '9') c = getchar (); sgn = (c = '-')? -1:1; ret = (c = '-')? 0 :( c-'0'); while (c = getchar (), c> = '0' & c <= '9 ') ret = ret * 10 + (c-'0'); ret * = sgn; return 1;} template <class T> inline void pt (T x) {if (x <0) {putchar ('-'); x =-x;} if (x> 9) pt (x/10 ); putchar (x % 10 + '0');} using namespace std; typedef long ll; const int N = 10100; const ll inf = 1e10; struct Edge {int, nex;} edge [N <1]; int head [N], edgenum; void add (int u, int v) {Edge E = {v, head [u]}; edge [edgenum] = E; head [U] = edgenum ++;} void init () {memset (head,-1, sizeof head); edgenum = 0;} int n; ll dp [N] [2];/* dp [I] [0]: the parent edge of I selects dp [I] [1]: I do not select */void up (ll & x, const ll & y) {if (y <x) x = y;} void dfs (int u, int fa) {dp [u] [0] = dp [u] [1] = inf; bool isleaf = true; ll a [3]; memset (a, 0, sizeof ); for (int I = head [u]; ~ I; I = edge [I]. nex) {int v = edge [I]. to; if (v = fa) continue; dfs (v, u); a [0] + = dp [v] [0]; a [1] + = dp [v] [1]; a [2] + = min (dp [v] [0], dp [v] [1]); isleaf = false;} if (isleaf) {dp [u] [0] = 100; dp [u] [1] = 0; return ;} /// // up (dp [u] [0], a [0] + 100); up (dp [u] [0], a [2] + 500); up (dp [u] [1], a [0]); ll B [3]; B [0] = B [1] = inf; for (int I = head [u]; ~ I; I = edge [I]. nex) {int v = edge [I]. to; if (v = fa) continue; up (dp [u] [0], a [0]-dp [v] [0] + dp [v] [1] + 175 ); B [2] =-dp [v] [0] + dp [v] [1]; sort (B, B + 3 );} up (dp [u] [1], a [0] + B [0] + B [1] + 175);} void input () {init (); rd (n); for (int I = 1, u, v; I <n; I ++) {rd (u); rd (v); add (u, v); add (v, u) ;}} int main () {int T; scanf ("% d", & T); while (T --) {input (); dfs (0, 0); // for (int I = 0; I <n; I ++) printf ("% d: % lld \ n ", I, dp [I] [0], dp [I] [1]); printf (" $ % lld \ n ", min (dp [0] [0], dp [0] [1]);} return 0 ;} /* 99100 10 23 22 43 53 63 73 960 10 20 33 44 570 11 22 32 42 55 650 10 20 450 10 470 10 20 30 40 50 670 10 10 21 21 33 45 25 6 */