嘟嘟嘟

这道题可以说是[HNOI2003]消防局的设立的升级版。距离从2改为了d。

辛亏d只有20,这也就是一个切入点。

令f[u][j]表示u四周 j - 1的距离需要被覆盖,g[u][j]表示u可以像四周覆盖 j 的距离。

考虑转移方程,令v为u的其中一个儿子:

1.f[u][j]:直接从v延伸而来:f[u][j] = Σ f[v][j - 1]

2.g[u][j]:用前几个儿子已经得出的g[u][j]去覆盖v:g[u][j] = g[u][j] + f[v][j];或者用v覆盖u:g[now][j] = f[now][j +1] +g[v][j + 1],所以g[now][j] = min{g[now][j] + f[v][j], f[now][j + 1] + g[v][j + 1]}.

对于f,可能距离小的比大的还优,所以还要再求一遍前缀最小值:f[now][j] = min{f[now][k]} (0 <= k < j)

同理对于g,可能覆盖距离大的比距离小的还优,所以后缀最小值:g[now][j] = min{g[now][k]} (j < k <= d)

最后考虑的是初值:显然g[now][j] = c[now] (1 <= j <= d)。然后如果这个点B神可能出现,f[now][0] = g[now][0] = c[now],表示这个点需要覆盖。

(代码折叠坏啦)

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 5e5 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = (ans << ) + (ans << ) + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} int n, d, m, c[maxn];
bool vis[maxn]; struct Edge
{
int nxt, to;
}e[maxn << ];
int head[maxn], ecnt = -;
void addEdge(int x, int y)
{
e[++ecnt] = (Edge){head[x], y};
head[x] = ecnt;
} int f[maxn][], g[maxn][];
void dfs(int now, int _f)
{
for(int i = ; i <= d; ++i) g[now][i] = c[now];
if(vis[now]) f[now][] = g[now][] = c[now];
g[now][d + ] = INF;
for(int i = head[now], v; i != -; i = e[i].nxt)
{
v = e[i].to;
if(v == _f) continue;
dfs(v, now);
for(int j = d; j >= ; --j) g[now][j] = min(g[now][j] + f[v][j], f[now][j + ] + g[v][j + ]);
for(int j = d; j >= ; --j) g[now][j] = min(g[now][j], g[now][j + ]);
f[now][] = g[now][];
for(int j = ; j <= d; ++j) f[now][j] += f[v][j - ];
for(int j = ; j <= d; ++j) f[now][j] = min(f[now][j], f[now][j - ]);
}
} int main()
{
Mem(head, -);
n = read(); d = read();
for(int i = ; i <= n; ++i) c[i] = read();
m = read();
for(int i = ; i <= m; ++i) {int x = read(); vis[x] = ;}
for(int i = ; i < n; ++i)
{
int x = read(), y = read();
addEdge(x, y); addEdge(y, x);
}
dfs(, );
write(f[][]), enter;
return ;
}

[JLOI2016/SHOI2016]侦察守卫的更多相关文章

  1. 洛谷 P3267 - [JLOI2016/SHOI2016]侦察守卫(树形 dp)

    洛谷题面传送门 经典题一道,下次就称这种"覆盖距离不超过 xxx 的树形 dp"为<侦察守卫模型> 我们考虑树形 \(dp\),设 \(f_{x,j}\) 表示钦定了 ...

  2. [JLOI2016/SHOI2016]侦察守卫(树形dp)

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

  3. P3267 [JLOI2016/SHOI2016]侦察守卫

    $ \color{#0066ff}{ 题目描述 }$ 小R和B神正在玩一款游戏.这款游戏的地图由N个点和N-1条无向边组成,每条无向边连接两个点,且地图是连通的.换句话说,游戏的地图是一棵有N个节点的 ...

  4. BZOJ4557:[JLOI2016/SHOI2016]侦察守卫——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4557 小R和B神正在玩一款游戏.这款游戏的地图由N个点和N-1条无向边组成,每条无向边连接两个点, ...

  5. 洛谷 P3267 [JLOI2016/SHOI2016]侦察守卫(树形dp)

    题面 luogu 题解 树形\(dp\) \(f[x][y]表示x的y层以下的所有点都已经覆盖完,还需要覆盖上面的y层的最小代价.\) \(g[x][y]表示x子树中所有点都已经覆盖完,并且x还能向上 ...

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

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

  7. Luogu3267 [JLOI2016/SHOI2016]侦察守卫 (树形DP)

    树形DP,一脸蒙蔽.看了题解才发现它转移状态与方程真不愧神题! \(f[x][y]\)表示\(x\)的\(y\)层以下的所有点都已经覆盖完,还需要覆盖上面的\(y\)层的最小代价. \(g[x][y] ...

  8. DP学习记录Ⅰ

    DP学习记录Ⅱ 前言 状态定义,转移方程,边界处理,这三部分想好了,就问题不大了.重点在状态定义,转移方程是基于状态定义的,边界处理是方便转移方程的开始的.因此最好先在纸上写出自己状态的意义,越详细越 ...

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

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

随机推荐

  1. php根据IP获取所在省份-淘宝api接口

    这里用的file_put_contents,你也可以用别的,直接怼代码: //拼接传递的参数$ip = '175.12.53.12' $opts = array( 'http'=>array( ...

  2. java gc 随记

    gc为garbage collection的缩写,中文翻译为垃圾回收.垃圾为不在使用的实例.变量,回收为释放垃圾所占用的内存空间. 学习过的C语言.C++语言,是没有垃圾回收机制的,因此需要软件工程师 ...

  3. 西数常用TREX命令

    西数常用TREX命令 trex命令:dut1 简便找盘idp或info did查看硬盘信息chkresfall检测固件smart 查看SMART表clrsmart 清SMART表svmod 0x.. ...

  4. SpringMVC 工作流程

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/baidu_36697353/article/details/64444147 SpringMVC 工 ...

  5. Maven+MyBatis 初试

    工作中一直使用的都是Hibernate,总是听见有人拿Mybatis和Hibernate做比较,今天尝试来看看. 一.用Maven建立web项目 此处参见 http://www.cnblogs.com ...

  6. pyhton基础中的要点一

    1.python变量的命名规范: (1)变量必须以数字,字母,下划线的任意组合 (2)变量建议用驼峰标识,或下划线 (3)变量要有可描述性 (4)不能以数字开头 (5)不能用python的关键字 (6 ...

  7. VC 在调用main函数之前的操作

    title: VC 在调用main函数之前的操作 tags: [VC++, 反汇编, C++实现原理] date: 2018-09-16 10:36:23 categories: VC++反汇编分析 ...

  8. 使用Calendar加一天,减一天

    public class Test { public static void main(String[] args) { Calendar c=Calendar.getInstance(); Simp ...

  9. GeoServer中WMS、WFS的请求规范(转载)

    1.背景 1.1WMS简介 Web地图服务(WMS)利用具有地理空间位置信息的数据制作地图.其中将地图定义为地理数据可视的表现.这个规范定义了三个操作:GetCapabitities返回服务级元数据, ...

  10. sqoop简单介绍

    一简介 Sqoop是一个用来将Hadoop和关系型数据库中的数据相互转移的工具,可以将一个关系型数据库(例如 : MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS ...