• 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 }
    人就像命运下的蝼蚁,谁也无法操控自己的人生.
  • 相关阅读:
    html基本标签练习
    实践1-qq邮箱主页
    html加强
    Date日期操作
    日期类的加减及java中所以日期类的操作算法大全
    讲解java异常
    关于Java并发编程的总结和思考
    删除map、list集合元素总结
    Jedis使用总结【pipeline】【分布式的id生成器】【分布式锁【watch】【multi】】【redis分布式】
    Java中的时间日期处理
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6023239.html
Copyright © 2020-2023  润新知