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 表示当前节点向下 ...
随机推荐
- go module配置
参考文章: http://c.biancheng.net/view/4774.html 1.
- python解析html
*参考 推荐BeautifulSoup http://blog.csdn.net/abclixu123/article/details/38502993 http://www.cnblogs.com/ ...
- [学习笔记] Hibernate 4.3.5 下载与安装
下载 http://hibernate.org/orm/releases/4.3/ https://sourceforge.net/projects/hibernate/files/hibernate ...
- php-fpm的参数优化
查看php-fpm的内存占用 1.查看php-fpm的进程个数 ps -ef |grep "php-fpm"|grep "pool"|wc -l 2.查看每个p ...
- 对于大于等于3的整数n,在区间【n,3/2 * n】中一定存在一个素数
对于大于3的整数n,在区间[n,3/2 * n]中一定存在一个素数
- private关键字 this关键字
基本类型的布尔值boolean定义get方法,名称应该为isMale 当方法的局部变量和类的成员变量重名的时候,根据就近原则,有限使用局部变量, 如果需要访问成员变量 则使用this.name 构造 ...
- Laravel 最佳实践
单一职责原则 一个类和一个方法应该只有一个责任. 例如: public function getFullNameAttribute() { if (auth()->user() &&am ...
- Symfony 服务配置 看这一篇就够了
对于刚接触 Symfony 的新手来说,如何配置服务是一件很困难的事情.虽然在 Symfony 的新版本的框架中加入了自动加载(autowire),基本上满足了一般的需求,但是如果你想深入了解“服务” ...
- adb shell dumpsys [options]的使用
adb shell dumpsys [options]该命令用于打印出当前系统信息,默认打印出设备中所有service的信息.由于service比较多,这里选几个用的比较多的service来进行讲解: ...
- python以不同方式打印输出九九乘法表
参考:http://www.cnblogs.com/suiy-160428/p/5594389.htmlpython输出 9*9 乘法口诀表 矩形输出九九乘法表: for i in range(1,1 ...