「JLOI / SHOI2016」侦查守卫

Posted ympc2005

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「JLOI / SHOI2016」侦查守卫相关的知识,希望对你有一定的参考价值。

树上的动态规划

对于一棵子树内的守卫,也可以覆盖子树外的节点,需要加一维来记录子树与外界的关系。

g[u][j] 表示覆盖完子树并且还可以覆盖离子树根节点距离不大于j的点的最小花费

f[u][j] 表示子树内只保证距离子树根节点距离不小于j的节点被覆盖的最小花费

讨论树的子树对于树的关系来转移:

u是v的父亲,则

g[u][j]=min(g[u][j]+f[v][j],g[v][j+1]+f[u][j+1])

f[u][j] = Σf[v][j-1]

g[u][j] = min(g[u][j], g[u][j+1])

f[u][j] = min(f[u][j], f[u][j-1]) 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 5e5 + 5, M = 25;
 5 
 6 int n, d, cnt, first[N], w[N], f[N][M], g[N][M], m, inf = 1e9;
 7 bool vis[N];
 8 struct Edge {
 9     int to, next;
10 } e[N<<1];
11 
12 void dfs(int u, int fa) {
13     if(vis[u]) f[u][0] = g[u][0] = w[u];
14     for(int i = 1; i <= d; i++) g[u][i] = w[u];
15     g[u][d + 1] = inf;
16     for(int i = first[u]; i != -1; i = e[i].next) {
17         int v = e[i].to;
18         if(v == fa) continue;
19         dfs(v, u);
20         for(int j = 0; j <= d; j++)
21            g[u][j] = min(g[u][j] + f[v][j], g[v][j + 1] + f[u][j + 1]);
22         for(int j = d; j >= 0; j--) g[u][j] = min(g[u][j], g[u][j + 1]);
23         f[u][0] = g[u][0];
24         for(int j = 1; j <= d; j++)
25            f[u][j] += f[v][j - 1];
26         for(int j = 1; j <= d; j++)
27            f[u][j] = min(f[u][j], f[u][j - 1]);
28     }
29 }
30 
31 void add(int u, int v) {
32     e[cnt] = (Edge) {v, first[u]};
33     first[u] = cnt++;
34 }
35 
36 int Read() {
37     int f = 1, res = 0;
38     char ch = getchar();
39     while(ch > 9 || ch < 0) {
40         if(ch == -) f =- 1;
41         ch = getchar();
42     }
43     while(ch >= 0 && ch <= 9) {
44         res = res*10 + ch - 0;
45         ch = getchar();
46     }
47     return res*f;
48 }
49 
50 int main() {
51     n = Read(); d = Read();
52     memset(first, -1, sizeof(first));
53     for(int i = 1; i <= n; i++)
54        w[i] = Read();
55     m = Read();
56     for(int i = 1; i <= m; i++)
57        vis[Read()] = 1;
58     for(int i = 1, u, v; i < n; i++) {
59         u = Read(); v = Read();
60         add(u, v); add(v, u);
61     } 
62     dfs(1, 0);
63     printf("%d
", f[1][0]);
64     return 0;
65 } 

 

以上是关于「JLOI / SHOI2016」侦查守卫的主要内容,如果未能解决你的问题,请参考以下文章

[JLOI2016/SHOI2016]侦察守卫(树形dp)

p3267 [JLOI2016/SHOI2016]侦察守卫

4557: [JLoi2016]侦察守卫|树形DP

4557: [JLoi2016]侦察守卫|树形DP

BZOJ4557 [JLoi2016]侦察守卫 树形dp

bzoj千题计划272:bzoj4557: [JLoi2016]侦察守卫