侦查守卫

小R和B神正在玩一款游戏。这款游戏的地图由 N 个点和 N-1 条无向边组成,每条无向边连接两个点,且地图是连通的。换句话说,游戏的地图是一棵有 N 个节点的树。

游戏中有一种道具叫做侦查守卫,当一名玩家在一个点上放置侦查守卫后,它可以监视这个点以及与这个点的距离在 D 以内的所有点。这里两个点之间的距离定义为它们在树上的距离,也就是两个点之间唯一的简单路径上所经过边的条数。在一个点上放置侦查守卫需要付出一定的代价,在不同点放置守卫的代价可能不同。

现在小R知道了所有B神可能会出现的位置,请你计算监视所有这些位置的最小代价。

对于所有的数据,N<=500000,D<=20

题解

  • 状态设计

假设当前到了 x 的子树,现在该合并 x 的第 k 个子树。

f[x][j] 表示 x 的前 k-1 个子树该覆盖的完全覆盖,而且还能向四周覆盖 j 层(不含 x )的最小代价。

对于第 k 个子树的意义就是,兄弟子树放置的守卫可以帮 x 的第 k 个子树覆盖前 j 层(第 1 层为 x 的子节点),那么相应的就要有一个状态来表示这个 可以让兄弟子树帮忙覆盖 的前 j 层。

g[x][j] 表示还需要覆盖 x 的前 k 个子树中的前 j 层(含 x),且第 j 层以下该覆盖的完全覆盖的最小代价。

  • 状态转移

要能向 x 的四周覆盖 j 层,只需要 x 的子节点中有一个子节点 z 能向上覆盖 j+1 层即可。所以

f[x][j] = min(f[x][j]+g[y][j] ,f[y][j+1]+g[x][j+1])

g[x][j] += g[y][j-1]

但是有可能更新后 x 能向上恰好覆盖 j 层的代价要小于能向上恰好覆盖 j-1 层的代价;也有可能 x 需要向下覆盖 j 层的代价小于再向下覆盖 j+1 层的代价。

所以将f的状态定义改为 向上覆盖至少j层的最小代价

同理,g的状态定义改为还需要覆盖至多j层的最小代价

所以要对f[x]做一个后缀最小值,g[x]做一个前缀最小值。

时间复杂度\(O(ND)\)。

#include<bits/stdc++.h>
#define co const
#define il inline
template<class T> T read(){
T x=0,w=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-') w=-w;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*w;
}
template<class T> il T read(T&x){
return x=read<T>();
}
using namespace std;
typedef long long LL; co int N=500000+10,D=21;
int n,dis,w[N],use[N];
vector<int> to[N];
int f[N][D],g[N][D]; void dfs(int x,int fa){
for(int i=1;i<=dis;++i) f[x][i]=w[x];
if(use[x]) g[x][0]=f[x][0]=w[x];
f[x][dis+1]=1e9;
for(int i=0;i<(int)to[x].size();++i){
int y=to[x][i];
if(y==fa) continue;
dfs(y,x);
for(int j=0;j<=dis;++j)
f[x][j]=min(f[x][j]+g[y][j],f[y][j+1]+g[x][j+1]);
for(int j=dis;j>=0;--j)
f[x][j]=min(f[x][j],f[x][j+1]);
g[x][0]=f[x][0];
for(int j=1;j<=dis;++j)
g[x][j]+=g[y][j-1];
for(int j=1;j<=dis;++j)
g[x][j]=min(g[x][j],g[x][j-1]);
}
}
int main(){
read(n),read(dis);
for(int i=1;i<=n;++i) read(w[i]);
for(int m=read<int>();m--;) use[read<int>()]=1;
for(int i=1;i<n;++i){
int x=read<int>(),y=read<int>();
to[x].push_back(y),to[y].push_back(x);
}
dfs(1,0);
printf("%d\n",g[1][0]);
return 0;
}

JLOI2016 侦查守卫的更多相关文章

  1. [BZOJ4557][JLOI2016]侦查守卫

    4557: [JLoi2016]侦察守卫 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 297  Solved: 200[Submit][Status ...

  2. BZOJ 4557 JLOI2016 侦查守卫 树形dp

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4557 题意概述: 给出一棵树,每个点付出代价w[i]可以控制距离和它不超过d的点,现在给 ...

  3. BZOJ 4557 (JLOI 2016) 侦查守卫

    4557: [JLoi2016]侦察守卫 Time Limit: 20 Sec Memory Limit: 256 MB Submit: 493 Solved: 342 [Submit][Status ...

  4. loj #2024. 「JLOI / SHOI2016」侦查守卫

    #2024. 「JLOI / SHOI2016」侦查守卫   题目描述 小 R 和 B 神正在玩一款游戏.这款游戏的地图由 nnn 个点和 n−1n - 1n−1 条无向边组成,每条无向边连接两个点, ...

  5. bzoj4557【JLOI2016】侦查守卫

    这道题对于我来说并不是特别简单,还可以. 更新一下blog 树形DP f[i][j]表示i的子树中,最高覆盖到i向下第j层的最小花费. g[i][j]表示i的子树全部覆盖,还能向上覆盖j层的最小花费. ...

  6. BZOJ 4557 侦查守卫

    好迷的树形dp... #include<iostream> #include<cstdio> #include<cstring> #include<algor ...

  7. 【LOJ】#2024. 「JLOI / SHOI2016」侦查守卫

    题解 童年的回忆! 想当初,这是我考的第一次省选,我当时初二,我什么都不会,然后看着这个东西,是不是能用我一个月前才会的求lca,光这个lca我就调了一个多小时= =,然后整场五个小时,我觉得其他题不 ...

  8. 解题:JLOI 2016 侦查守卫

    题面 经典的$cov-unc$树形dp(这词是你自己造的吧=.=) 设$cov[i][j]$表示覆盖完$i$的子树后至少向外再覆盖$j$层的最小代价,$unc[i][j]$表示$i$的子树中还剩下至少 ...

  9. bzoj4557侦查守卫

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4557 树形DP.和“河流”有点像,也有一个类似“承诺”的东西. 就是用 f 表示当前节点向下 ...

随机推荐

  1. OpenCV.CV_FOURCC

    1.c++ - how to use CV_CAP_PROP_FOURCC_ - Stack Overflow.html(https://stackoverflow.com/questions/223 ...

  2. 第一个go程序

    进入到工作空间中(我的是$HOME/go, 所以使用cd $HOME/go命令直接进入) 然后创建一个目录 src/hello( mkdir src/hello), 然后进入到该目录中(cd src/ ...

  3. JavaScript 检测值

    了解常见的真值和假值,可以增强判断能力.在使用if判断时,提升编码速度. 了解常见的检测和存在,一样可以增强判断能力,而且是必须掌握的. 数组和对象被视为真值 1 2 3 4 5 6 7 8 9 10 ...

  4. 子组件props接受父组件传递的值,能不能修改的问题

    参考链接:https://www.cnblogs.com/pangchunlei/p/11139356.html

  5. 编写一个自定义事件类,包含on/off/emit/once方法

    function Event() { this._events = {}; } Event.prototype.on = function(type, fn) { if (!this._events[ ...

  6. docker 运行pptpd服务器

      今天试着用docker搭了一下pptpd服务器,感觉清爽不少(当然是踩坑之后的啦),特此记录.   使用的镜像: mmontagna/docker-vpn-pptp   由于是现成的镜像,所以我们 ...

  7. [转帖]linux下CPU、内存、IO、网络的压力测试,硬盘读写速度测试,Linux三个系统资源监控工具

    linux下CPU.内存.IO.网络的压力测试,硬盘读写速度测试,Linux三个系统资源监控工具 https://blog.51cto.com/hao360/1587165 linux_python关 ...

  8. TeX教程

    转自 [抢工作向]一个更适合玩物理的同学的论坛TeX教程 1. 基础知识 如何在你的帖子里插入一个\(\TeX\)环境来写公式呢?答案其实很简单,对于不同的要求,我们有两种方法. 第一种只需要在\(\ ...

  9. 4.Linux系统命令及其使用详解

    运维工程师必会的109个Linux命令   文件管理basename:从文件名中去掉路径和扩展名 cat:把档案串连接后传到基本输出(屏幕或加 > filename 到另一个档案)cd:切换目录 ...

  10. Job和Service

    Job及CronJob: ---apiVersion: batch/v1kind: Jobmetadata:  name: job-demospec:  template:    metadata:  ...