JLOI2016 侦查守卫
侦查守卫
小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 侦查守卫的更多相关文章
- [BZOJ4557][JLOI2016]侦查守卫
4557: [JLoi2016]侦察守卫 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 297 Solved: 200[Submit][Status ...
- BZOJ 4557 JLOI2016 侦查守卫 树形dp
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4557 题意概述: 给出一棵树,每个点付出代价w[i]可以控制距离和它不超过d的点,现在给 ...
- BZOJ 4557 (JLOI 2016) 侦查守卫
4557: [JLoi2016]侦察守卫 Time Limit: 20 Sec Memory Limit: 256 MB Submit: 493 Solved: 342 [Submit][Status ...
- loj #2024. 「JLOI / SHOI2016」侦查守卫
#2024. 「JLOI / SHOI2016」侦查守卫 题目描述 小 R 和 B 神正在玩一款游戏.这款游戏的地图由 nnn 个点和 n−1n - 1n−1 条无向边组成,每条无向边连接两个点, ...
- bzoj4557【JLOI2016】侦查守卫
这道题对于我来说并不是特别简单,还可以. 更新一下blog 树形DP f[i][j]表示i的子树中,最高覆盖到i向下第j层的最小花费. g[i][j]表示i的子树全部覆盖,还能向上覆盖j层的最小花费. ...
- BZOJ 4557 侦查守卫
好迷的树形dp... #include<iostream> #include<cstdio> #include<cstring> #include<algor ...
- 【LOJ】#2024. 「JLOI / SHOI2016」侦查守卫
题解 童年的回忆! 想当初,这是我考的第一次省选,我当时初二,我什么都不会,然后看着这个东西,是不是能用我一个月前才会的求lca,光这个lca我就调了一个多小时= =,然后整场五个小时,我觉得其他题不 ...
- 解题:JLOI 2016 侦查守卫
题面 经典的$cov-unc$树形dp(这词是你自己造的吧=.=) 设$cov[i][j]$表示覆盖完$i$的子树后至少向外再覆盖$j$层的最小代价,$unc[i][j]$表示$i$的子树中还剩下至少 ...
- bzoj4557侦查守卫
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4557 树形DP.和“河流”有点像,也有一个类似“承诺”的东西. 就是用 f 表示当前节点向下 ...
随机推荐
- Android之makefile
在Android的源代码中,随处可见Makefile,那么Makefile到底是用来干嘛的呢?其实Makefile和Maven.ANT.Gradle一样,属于构建工具,当项目比较庞大的时候,就可以使用 ...
- Vue2.4+新增属性.sync、$attrs、$listeners
参考链接:https://www.jianshu.com/p/4649d317adfe
- GxDlms编译
目录 GxDlms编译 title: GxDlms编译 date: 2019/12/5 13:36:37 toc: true --- GxDlms编译 C++版本如果要编译动态库,项目>属性需要 ...
- 【leetcode算法-简单】13. 罗马数字转整数
[题目描述] 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 II ,即为两个并列 ...
- UWP笔记-使用FFmpeg编解码
在开发UWP媒体应用的时候,使用的MediaElement可以支持主流的格式,不过还是有些格式本地编解码器是不支持的,如.flv..rmvb等,这里讲到的是第三方开源库FFmpeg,可以直接播放更多的 ...
- Python基础学习路径
1. Python数据结构 1. 基本数据类型(整数.小数.字符) 1.基本数据类型有5种:int bool float complex long 2.每一种数据类型该如何定义 3.数据类型之间可以强 ...
- Devexpress xaf针对某个用户登录后在面板中设置导航无效的解决方法
Devexpress xaf框架生成的项目默认情况下导航栏是显示在左侧,有时候我们用某个账户登录后,发现导航栏无法显示在左侧,操作十分不方便.我们可以去数据库删除当前登录用户的自定义布局 解决方法如下 ...
- ts转js 并压缩
1,在线编译,进入typescript官网http://www.typescriptlang.org/,点击里面的playground就可以直接写代码了. 2,在本地编译运行Typescript需要使 ...
- 【广搜】Knight Moves
题目描述 Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights fr ...
- Foo Fighters CodeForces - 1148F
大意: 给定$n$个二元组$(val_i,mask_i)$. 保证$\sum val_i$不为$0$. 要求选择一个数$s$, 对于每个二元组$(val_i,mask_i)$, 若$s\& m ...