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

树形DP。和“河流”有点像,也有一个类似“承诺”的东西。

  就是用 f 表示当前节点向下 j 层之下的需覆盖点已覆盖的费用。答案可以是 f [ root ] [0] 。(root是随便一个点)

    最好把当前节点看作第1层而不是第0层,这样就能用0表示当前节点的子树全覆盖了。

  为了转移,引入一个 g ,表示当前点在自己子树全覆盖的基础上可以向外覆盖 j 层。这时当前节点可以自然地看作第0层了。

    这也是为什么 f 表示的是“向下 j 层之下的点全覆盖”而不是“向下 j 层全覆盖”。就是为了方便转移。

      没错,因为如果记成“向下 j 层全覆盖”,那么记录下“还有一些没覆盖”这一状态也根本没用,因为兄弟节点都是从上往下帮自己覆盖的;

      而像这样记录成“向下还有 j 层没覆盖”,就有更多“把它们覆盖好”的机会,也方便转移等等,变得很顺畅!

具体转移的时候,发现 g 的转移依赖 f (上一次的 f 值),而 f 的转移不依赖 g ,所以要先求g的值。

  可以用g[0]来更新 f [0] 的值,因为f [0] 是从当前节点的孩子们的 f 那里转移不过来的。

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=5e5+,D=;const ll INF=0x7fffffff;
int n,m,d,head[N],xnt;
ll a[N],f[N][D],g[N][D];
bool need[N];
struct Edge{
int next,to;
Edge(int n=,int t=):next(n),to(t) {}
}edge[N<<];
void add(int a,int b)
{
edge[++xnt]=Edge(head[a],b);head[a]=xnt;
edge[++xnt]=Edge(head[b],a);head[b]=xnt;
}
void dfs(int cr,int fa)
{
f[cr][]=g[cr][]=need[cr]?a[cr]:;//只有根节点时的状态
for(int j=;j<=d;j++)g[cr][j]=a[cr];//初值
g[cr][d+]=INF;
for(int i=head[cr],v;i;i=edge[i].next)
{
if((v=edge[i].to)==fa)continue;
dfs(v,cr);
for(int j=;j<=d;j++)g[cr][j]=min(g[cr][j]+f[v][j],f[cr][j+]+g[v][j+]);//从0开始
for(int j=d;j;j--)g[cr][j-]=min(g[cr][j-],g[cr][j]);
f[cr][]=g[cr][]; //
for(int j=;j<=d;j++)f[cr][j]+=f[v][j-]; //这个不要放在28行之前,因为该行要用到上一次的值
for(int j=;j<=d;j++)f[cr][j]=min(f[cr][j],f[cr][j-]);
}
}
int main()
{
scanf("%d%d",&n,&d);for(int i=;i<=n;i++)scanf("%lld",&a[i]);
scanf("%d",&m);int tmp;for(int i=;i<=m;i++){scanf("%d",&tmp);need[tmp]=;}
int x,y;
for(int i=;i<n;i++)
{
scanf("%d%d",&x,&y);add(x,y);
}
// memset(g,1,sizeof g);
dfs(,);
printf("%lld",f[][]);
return ;
}

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

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

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

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

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

  3. JLOI2016 侦查守卫

    侦查守卫 小R和B神正在玩一款游戏.这款游戏的地图由 N 个点和 N-1 条无向边组成,每条无向边连接两个点,且地图是连通的.换句话说,游戏的地图是一棵有 N 个节点的树. 游戏中有一种道具叫做侦查守 ...

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

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

  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. BZOJ 4557 JLOI2016 侦查守卫 树形dp

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

随机推荐

  1. python----tkinterm模块

    python tkinter学习——布局   目录 一.pack() 二.grid() 三.place() 四.Frame() 正文 布局 一.pack() pack()有以下几个常用属性: side ...

  2. iptables疑问总结(一)

    1.关于-j 的return说明 1. 从一个CHAIN里可以jump到另一个CHAIN, jump到的那个CHAIN是子CHAIN.2. 从子CHAIN return后,回到触发jump的那条规则, ...

  3. Prism 4 文档 ---第2章:初始化Prism应用程序

     这一章节介绍Prism应用程序启动和运行时发生的内容.Prism应用程序在启动时需要有注册和配置的过程,这就是所谓的自自启动程序. 什么是自启动引导程序?     引导程序是一个类,它负责使用Pri ...

  4. matlab cvx工具包安装

    cvx是凸函数优化的工具包 官网下载地址,http://cvxr.com/cvx/download/ 1 解压到任意文件,最好不要是matlab中的toolbox, 2 假如你解压倒了c盘sample ...

  5. Qt实现简单的单例模式

    单例模式十分的常见也很常用,Boost库中就有单例的泛型实现,Qt中,可以利用原子指针来实现一个单例模式: class SingleTon{ public: static SingleTon & ...

  6. js 验证对象是否为数组

    一.方法一:用到了原型 由于typeof检测数组,只会显示其为object,并不会详细到告诉我们是否为array,所以我们可以自己写个js用原型来检测: <script> /** * * ...

  7. 剑指offer--51.表示数值的字符串

    正则好舒服, ------------------------------------------------------------------------------------------ 时间 ...

  8. mysql 数据传输报错 MySQL server has gone away With statement:

    利用navicat premium 拷贝数据库时,报错MySQL server has gone away With statement:, 造成这样的原因一般是sql操作的时间过长,或者是传送的数据 ...

  9. Python matplotlib 数据分布

    利用plt.hist() import matplotlib.pylab as plt %matplotlib inline plt.figure(figsize=(21, 12)) plt.hist ...

  10. python2 使用matplotlib

    背景 由於pyh在python3上沒法兒用,所以只能在python2上用pyh2 相應地也要在python2上使用matplotlib 下載 有兩種方法,pip & dnf pip爲: pip ...