https://www.lydsy.com/JudgeOnline/problem.php?id=4557

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

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

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

dp状态很好想,但是这个式子我菜我是真的推不出来,其他的巨佬切题的速度叹为观止,只能感叹我的智商摆在这里。

参考:https://www.luogu.org/blog/zcysky/solution-p3267

一眼是个树形dp,二眼$d$很小,可以直接做成一维状态,那么直接设$f[i][j]$为$i$子树从$i$往下$j$层都没有覆盖的代价,$g[i][j]$为$i$的子树全覆盖,往上还可以覆盖$j$层的代价。二者正好是互补的。

(PS:层数也包括i本身,换句话说,$j=0$时$i$并没有被覆盖,我在这里纠结了很久。)

(PPS:既然$g[i][j]$都可以覆盖上$j$层,那它也能覆盖下$j$层。)

之后对于dp式子慢慢剖析因为我自己都云里雾里的。

边界就是当点$u$为关键点时$f[u][0]=g[u][0]=w[u]$这个点一定是要放一个的,如果不是的话显然我们就不需要放了,初值为0。

初始化就不说了。

对于每个儿子结点v,我们有:

$g[u][j]=min(g[u][j]+f[v][j],g[v][j+1]+f[u][j+1])$(所以明白f和g是互补的才能看懂)

当然也有可能出现这种的:$g[u][j]=min(g[u][j],g[u][j+1])$

推完g来推f,首先$f[u][0]=g[u][0]$因为此时二者状态等价。

然后显然的,$f[u][j]+=f[v][j-1]$

以及也有可能出现这种的:$f[u][j]=min(f[u][j],f[u][j-1])$

(所以其实核心还是在状态含义上而非式子,含义搞懂式子就很显然了。)

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e5+5;
const int D=21;
const int INF=1e9;
inline int read(){int X=0,w=0;char ch=0;while(!isdigit(ch)){w|=ch=='-';ch=getchar();}while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X;
}
struct node{int to,nxt;
}e[N*2];
int n,d,m,cnt,head[N],w[N];
int f[N][D],g[N][D];
bool im[N];
inline void add(int u,int v){e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;
}
void dfs(int u,int fa){if(im[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=head[u];i;i=e[i].nxt){int v=e[i].to;if(v==fa)continue;dfs(v,u);for(int j=d;j>=0;j--)g[u][j]=min(g[u][j]+f[v][j],g[v][j+1]+f[u][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+1;j++)f[u][j]+=f[v][j-1];for(int j=1;j<=d+1;j++)f[u][j]=min(f[u][j],f[u][j-1]);}
}
int main(){n=read(),d=read();for(int i=1;i<=n;i++)w[i]=read();m=read();for(int i=1;i<=m;i++)im[read()]=1;for(int i=1;i<n;i++){int u=read(),v=read();add(u,v);add(v,u);}dfs(1,0);printf("%d\n",f[1][0]);return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

转载于:https://www.cnblogs.com/luyouqi233/p/9193761.html

BZOJ4557:[JLOI2016/SHOI2016]侦察守卫——题解相关推荐

  1. Luogu 3267 [JLOI2016/SHOI2016]侦察守卫

    以后要记得复习鸭 BZOJ 4557 大佬的博客 状态十分好想,设$f_{x, i}$表示以覆盖完$x$为根的子树后还能向上覆盖$i$层的最小代价,$g_{x, i}$表示以$x$为根的子树下深度为$ ...

  2. BZOJ4557 JLOI2016侦察守卫(树形dp)

    下称放置守卫的点为监控点.设f[i][j]为i子树中深度最大的未被监视点与i的距离不超过j时的最小代价,g[i][j]为i子树中距离i最近的监控点与i的距离不超过j且i子树内点全部被监视时的最小代价. ...

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

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

  4. 2019年7月训练记录(更新ing)

    前言 本月上半月训练记录可详见:2019年暑假绍兴集训. \(Jul\ 15th\) 早上到机房先做了一道一直想做的板子题:[洛谷4781][模板]拉格朗日插值,发现拉格朗日插值也并没有想象中那么难. ...

  5. [暑假的bzoj刷水记录]

    (这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊  堆一起算了 隔一段更新一下.  7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...

  6. bzoj 4557: [JLoi2016]侦察守卫 树归

    bzoj 4557: [JLoi2016]侦察守卫 设f[x][j]表示覆盖以x为根的子树的所有应该被覆盖的节点,并且以x为根的子树向下j层全部被覆盖的最小代价. 设g[x][j]表示与x距离大于j全 ...

  7. BZOJ4596:[SHOI2016]黑暗前的幻想乡——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4596 https://www.luogu.org/problemnew/show/P4336#su ...

  8. 洛谷 P4336 [SHOI2016] 黑暗前的幻想乡 题解

    前置芝士 Kirchhoff 矩阵树定理 Kirchhoff矩阵树定理解决了一个问题:对于一个确定的无向图,其究竟有多少个生成树? 对于一个无向图,我们拥有其邻接矩阵 A\bf{A}A. 这里的邻接矩 ...

  9. 【BZOJ4596】[Shoi2016]黑暗前的幻想乡 容斥+矩阵树定理

    [BZOJ4596][Shoi2016]黑暗前的幻想乡 Description 幽香上台以后,第一项措施就是要修建幻想乡的公路.幻想乡有 N 个城市,之间原来没有任何路.幽香向选民承诺要减税,所以她打 ...

最新文章

  1. python网格搜索核函数_机器学习笔记——模型调参利器 GridSearchCV(网格搜索)参数的说明...
  2. v-if 表单验证_避免许多if块进行验证检查
  3. mysql 主从同步-读写分离
  4. 信号捕捉(signal、sigaction)
  5. 1.rabbitmq 集群版安装及使用nginx进行四层负载均衡设置
  6. JavaWeb应用配置文件安全解决方案
  7. mysql5.6.36源码安装_CentOS 7下rpm安装MySQL 5.6.36
  8. WebBrowser的Cookie操作
  9. Intel 芯片集被曝漏洞,可导致加密数据被盗
  10. Unity3D引用dll打包发布的问题及解决
  11. Java实现面向对象编程
  12. Windows11设置任务栏为小图标
  13. 这个对老爸老妈有好处
  14. csdn邻家割草_如何维护割草机,使其永远持续(几乎)
  15. 音视频开发大厂面试题(快手、百度、字节)
  16. FigDraw 20. SCI文章中绘图之马赛克图 (mosaic)
  17. 快递鸟基于java功能打印电子面单api接口
  18. 王者舰队服务器维护需要几天,王者舰队怎么快速获取金币 金币快速获得方法...
  19. matlab设置线条颜色宽度线型
  20. Android - 集成高德地图API(搜索,地图,定位)

热门文章

  1. 如何用Mybatis分库分表
  2. tomcat源码 Connector
  3. linux下用户操作
  4. PHP程序性能优化的50种方法
  5. java程序员招聘现场
  6. 多项目开发下的dll文件管理
  7. eclipse解决Android Library Project jar包重复导致的问题
  8. ldd随笔(1)-linux设备模型
  9. 数据契约(DataContract)
  10. 闲话WPF之十(Dependency属性 [2] )