树形DP,恩然后就不会了。。。
先写了个错的离谱程序。。。果然WA了
然后开始乱搞,欸,对了!
令f[i], g[i], h[i]分别表示i号节点自己放士兵,被儿子上的士兵控制,不被儿子上的士兵控制但被父亲上的士兵控制的情况下,以i为子树中最少的士兵数
F[i], G[i], H[i]表示对应的方案数,然后这方程写的沁人心脾。。。看程序吧
1 /************************************************************** 2 Problem: 2314 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:3224 ms 7 Memory:99512 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 13 using namespace std; 14 typedef long long ll; 15 const int N = 5e5 + 5; 16 const int inf = 1e9; 17 const int mod = 1032992941; 18 const int Maxlen = N * 15; 19 20 struct edge { 21 int next, to; 22 edge() {} 23 edge(int _n, int _t) : next(_n), to(_t) {} 24 } e[N << 1]; 25 26 int n; 27 int first[N], tot; 28 ll f[N], g[N], h[N]; 29 ll F[N], G[N], H[N]; 30 ll ans; 31 bool vis[N]; 32 char buf[Maxlen], *c = buf; 33 int Len; 34 35 inline int read() { 36 int x = 0; 37 while (*c < '0' || '9' < *c) ++c; 38 while ('0' <= *c && *c <= '9') 39 x = x * 10 + *c - '0', ++c; 40 return x; 41 } 42 43 inline void Add_Edges(int x, int y) { 44 e[++tot] = edge(first[x], y), first[x] = tot; 45 e[++tot] = edge(first[y], x), first[y] = tot; 46 } 47 48 #define y e[x].to 49 void dfs(int p) { 50 int x, mn; 51 ll t; 52 vis[p] = 1; 53 f[p] = 1, g[p] = inf, h[p] = 0; 54 F[p] = G[p] = H[p] = 1; 55 for (x = first[p]; x; x = e[x].next) 56 if (!vis[y]) { 57 dfs(y); 58 59 mn = min(min(f[y], g[y]), h[y]), t = 0; 60 if (f[y] == mn) t += F[y]; 61 if (g[y] == mn) t += G[y]; 62 if (h[y] == mn) t += H[y]; 63 f[p] += mn, (F[p] *= t) %= mod; 64 65 mn = min(min(g[p] + f[y], g[p] + g[y]), h[p] + f[y]), t = 0; 66 if (g[p] + f[y] == mn) t += G[p] * F[y]; 67 if (g[p] + g[y] == mn) t += G[p] * G[y]; 68 if (h[p] + f[y] == mn) t += H[p] * F[y]; 69 g[p] = mn, G[p] = t % mod; 70 71 h[p] += g[y], (H[p] *= G[y]) %= mod; 72 } 73 } 74 #undef y 75 76 int main() { 77 Len = fread(c, 1, Maxlen, stdin); 78 buf[Len] = '\0'; 79 int i, x, y; 80 n = read(); 81 for (i = 1; i < n; ++i) { 82 x = read(), y = read(); 83 Add_Edges(x, y); 84 } 85 dfs(1); 86 printf("%lld\n", min(f[1], g[1])); 87 printf("%lld\n", f[1] == g[1] ? (F[1] + G[1]) % mod : f[1] < g[1] ? F[1] : G[1]); 88 return 0; 89 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen