bzoj 4557: [JLoi2016]侦察守卫 树归

    bzoj 4557: [JLoi2016]侦察守卫

设f[x][j]表示覆盖以x为根的子树的所有应该被覆盖的节点,并且以x为根的子树向下j层全部被覆盖的最小代价。

设g[x][j]表示与x距离大于j全部应该覆盖的节点全部被覆盖的最小代价。

f[u][j] = min{f[u][j]+g[v][j],g[u][j+1]+f[v][j+1],f[u][j+1]}

g[u][j] = min{g[u][j-1],g[u][j]+g[v][j-1]}

边界f[u][d+1] = inf;f[u][i] = c[u];(i <= d) f[u][0] = c[u] or  0

g[u][0] = f[u][0];

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 inline void read(int &x){
 9     x=0;char ch;bool flag = false;
10     while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
11     while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
12 }
13 inline int cat_max(const ll &a,const ll &b){return a>b ? a:b;}
14 inline int cat_min(const ll &a,const ll &b){return a<b ? a:b;}
15 const int maxn = 500010;
16 const int maxd = 24;
17 struct Edge{
18     int to,next;
19 }G[maxn<<1];
20 int head[maxn],cnt;
21 void add(int u,int v){
22     G[++cnt].to = v;
23     G[cnt].next = head[u];
24     head[u] = cnt;
25 }
26 ll f[maxn][maxd],g[maxn][maxd];
27 int c[maxn],fa[maxn],d;
28 bool h[maxn];
29 #define v G[i].to
30 void dfs(int u){
31     if(h[u]) f[u][0] = g[u][0] = c[u];
32     else f[u][0] = g[u][0] = 0;
33     for(int i=1;i<=d;++i) f[u][i] = c[u];
34     f[u][d+1] = 1000LL*maxn;
35     for(int i = head[u];i;i=G[i].next){
36         if(v == fa[u]) continue;
37         fa[v] = u;
38         dfs(v);
39         for(int j=d;j>=0;--j){
40             f[u][j] = cat_min(cat_min(f[u][j]+g[v][j],g[u][j+1]+f[v][j+1]),f[u][j+1]);
41         }
42         g[u][0] = f[u][0];
43         for(int j=1;j<=d+1;++j){
44             g[u][j] = cat_min(g[u][j-1],g[u][j] + g[v][j-1]);
45         }
46     }
47 }
48 #undef v
49 int main(){
50  
51     int n;read(n);read(d);
52     for(int i=1;i<=n;++i) read(c[i]);
53     int m;read(m);
54     for(int i=1,x;i<=m;++i) read(x),h[x] = true;
55     for(int i=1,u,v;i<n;++i){
56         read(u);read(v);
57         add(u,v);add(v,u);
58     }
59     dfs(1);
60     printf("%lld
",g[1][0]);
61     getchar();getchar();
62     return 0;
63 }
人就像命运下的蝼蚁,谁也无法操控自己的人生.
原文地址:https://www.cnblogs.com/Skyminer/p/6023239.html