zoukankan      html  css  js  c++  java
  • 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 }
    人就像命运下的蝼蚁,谁也无法操控自己的人生.
  • 相关阅读:
    有关 JavaScript 的 10 件让人费解的事情
    Apache ab介绍1
    Oracle Raw,number,varchar2... 转换
    Flex开发者需要知道的10件事
    linux命令之nice
    JavaIO复习和目录文件的复制
    使用php获取网页内容
    linux 安装sysstat使用iostat、mpstat、sar、sa
    SQL Injection 实战某基金
    ubuntu root锁屏工具
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6023239.html
Copyright © 2011-2022 走看看