zoukankan      html  css  js  c++  java
  • 洛谷 P3267 [JLOI2016/SHOI2016]侦察守卫(树形dp)

    题面

    luogu

    题解

    树形(dp)

    (f[x][y]表示x的y层以下的所有点都已经覆盖完,还需要覆盖上面的y层的最小代价。)
    (g[x][y]表示x子树中所有点都已经覆盖完,并且x还能向上覆盖y层的最小代价。)

    对于 (u->v), (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]))

    Code

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    template<class T> inline void read(T &x) {
        x = 0; RG char c = getchar(); bool f = 0;
        while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
        while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
        x = f ? -x : x;
        return ;
    }
    template<class T> inline void write(T x) {
        if (!x) {putchar(48);return ;}
        if (x < 0) x = -x, putchar('-');
        int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
        for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
    }
    const int N = 500010, INF = 1e9;
    int n, d, w[N];
    struct node {
        int to, next;
    }G[N<<1];
    int last[N], gl;
    bool vis[N];
    void add(int x, int y) {
        G[++gl] = (node) {y, last[x]};
        last[x] = gl;
    }
    int f[N][22], g[N][22];
    void dfs(int u, int fa) {
        if (vis[u]) f[u][0] = g[u][0] = w[u];
        for (int i = 1; i <= d; i++) g[u][i] = w[u];
        g[u][d+1] = INF;
        for (int i = last[u]; i; i = G[i].next) {
            int v = G[i].to;
            if (v == fa) continue;
            dfs(v, u); 
        }
        for (int i = last[u]; i; i = G[i].next) {
            int v = G[i].to;
            if (v == fa) continue;
            for (int j = 0; j <= d; j++) g[u][j] = min(g[u][j]+f[v][j], f[u][j+1]+g[v][j+1]);
            for (int j = d; j >= 0; j--) g[u][j] = min(g[u][j], g[u][j+1]);
            f[u][0] = g[u][0];
            for (int j = 1; j <= d; j++) f[u][j] += f[v][j-1];
            for (int j = 1; j <= d; j++) f[u][j] = min(f[u][j], f[u][j-1]);
        }
        return ;
    }
    
    int main() {
        read(n); read(d);
        for (int i = 1; i <= n; i++) read(w[i]);
        int m; read(m);
        for (int i = 1; i <= m; i++) {
            int x; read(x);
            vis[x] = 1;
        }
        for (int i = 1; i < n; i++) {
            int x, y; read(x); read(y);
            add(x, y); add(y, x);
        }
        dfs(1, 0);
        printf("%d
    ", g[1][0]);
        return 0;
    }
    
    
  • 相关阅读:
    H5移动前端完美布局之-margin百分比的使用
    javascript 一个关于时间排序的算法(一个页面多个倒计时排序)
    html5 getComputedStyle + resize 实现动态宽高度等比响应式页面设计
    Windows 下关于转码的函数
    项目编译完之后自动提交
    eclipse 包含头文件出错
    Eclipse 包含头文件 添加环境变量
    linux下mongodb程序和c++客户端的编译
    简单谈谈消息发送缓冲区
    epoll 性能分析(解决占用CPU 过高问题)2
  • 原文地址:https://www.cnblogs.com/zzy2005/p/10242514.html
Copyright © 2011-2022 走看看