题目大意

一颗 \(n(1\leq n\leq 5\times 10^5)\) 个节点的树,在某一点 \(i\) 花费 \(w_{i}(w_{i}\leq 1000)\) 放置一个侦察守卫后可以监视到所有到 \(i\) 的距离 \(\leq d(d\leq 20)\) 的点, 有 \(m(m\leq n)\)个给定的关键节点需要监视,求能够监视到全部 \(m\) 个节点所需要的最小花费。

思路

设 \(f[i,x]\) 为监视到以 \(i\) 为根的子树中的全部关键点,并且可以向上监视到距离不小于 \(i\) 的节点的最小花费; \(g[i,x]\) 为至少监视到了以 \(i\) 为根的子树中的全部的与 \(i\) 的距离 \(\geq x\) 的关键点所需要的最小花费。在合并子树的过程中,对于 \(i\) 的每一个儿子 \(j\) ,我们可以得到:

\[f[i,x]=min(f[i,x]+g[j,x],g[i,x+1]+f[j,x+1])
\]
\[g[i,x]=g[i,x]+g[j,x-1]
\]

此外,由我们对状态的定义,显然有:

\[f[i,x]=min(f[i,x],f[i,x+1])
\]
\[g[i,x]=min(g[i,x],g[i,x-1])
\]

对于初始值,一开始先将所有 \(f\) 初始为 \(inf\) 。考虑到每一个子树一开始只有一个根节点 \(i\) ,于是,如果 \(i\) 是关键点, 那么 \(g[i,0]=f[i,0]=w_{i}\) ,否则, \(g[i,0]=f[i,0]=0\) ,因为此时 \(g\) 与 \(f\) 都恰好表示仅考虑节点 \(i\) 时的情况。如果 \(x\neq 0\) ,因为要向上监视,所以此处必须有一个侦察守卫,所以对于所有 \(1\leq x\leq d\) , \(f[i,x]=w_{i}\) 。

在每次与一个子树合并时,要先计算 \(f\) ,后计算 \(g\) 。因为 \(f\) 的转移方程中需要用到一个尚未与新的子树合并的 \(g\) 。此外由于 \(g[i,0]\) 不能通过转移方程得到,每次合并时计算完 \(f\) 后,需要令 \(g[i,0]=f[i,0]\) 。复杂度 \(O(nd)\) 。

代码

#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
#define all(x) x.begin(),x.end()
//#define int LL
//#define lc p*2+1
//#define rc p*2+2
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#pragma warning(disable : 4996)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const double eps = 1e-8;
const LL MOD = 1000000007;
const LL mod = 998244353;
const int maxn = 500010; vector<int>G[maxn];
int N, D, M, W[maxn];
bool key[maxn];
int f[maxn][25], g[maxn][25]; void add_edge(int from, int to)
{
G[from].push_back(to);
G[to].push_back(from);
} void dfs(int v, int p)
{
if (key[v])
f[v][0] = g[v][0] = W[v];
else
f[v][0] = g[v][0] = 0;
for (int i = 1; i <= D; i++)
f[v][i] = W[v];
for (int i = 0; i < G[v].size(); i++)
{
int to = G[v][i];
if (to == p)
continue;
dfs(to, v);
for (int j = 0; j <= D; j++)
f[v][j] = min(f[v][j] + g[to][j], f[to][j + 1] + g[v][j + 1]);
for (int j = D; j >= 0; i--)
f[v][j] = min(f[v][j], f[v][j + 1]);
g[v][0] = f[v][0];
for (int j = 1; j <= D; j++)
g[v][j] += g[to][j - 1];
for (int j = 1; j <= D; j++)
g[v][j] = min(g[v][j], g[v][j - 1]);
}
} void solve()
{
int ans = inf;
dfs(1, 0);
for (int i = 0; i <= D; i++)
ans = min(f[1][i], ans);
cout << ans << endl;
} int main()
{
IOS;
memset(f, inf, sizeof(f));
cin >> N >> D;
for (int i = 1; i <= N; i++)
cin >> W[i];
cin >> M;
int b;
for (int i = 1; i <= M; i++)
{
cin >> b;
key[b] = true;
}
int u, v;
for (int i = 1; i < N; i++)
{
cin >> u >> v;
add_edge(u, v);
}
solve(); return 0;
}

洛谷P3267.侦察守卫的更多相关文章

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

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

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

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

  3. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  4. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  5. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  6. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  7. 洛谷P1710 地铁涨价

    P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交  讨论  题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...

  8. 洛谷P1371 NOI元丹

    P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交  讨论  题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...

  9. 洛谷P1538迎春舞会之数字舞蹈

    题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...

随机推荐

  1. Druid未授权访问实战利用

    Druid未授权访问实战利用 ​ 最近身边的同学都开始挖src了,而且身边接触到的挖src的网友也是越来越多.作者也是在前几天开始了挖src之路.惊喜又遗憾的是第一次挖src就挖到了一家互联网公司的R ...

  2. Android Studio如何查看自己设计的数据库

    首先点击左上角进入Device File Explorer 进入后 点击data-data 找到你的项目名称 进入后点击你建立的数据库 一步步按照提示进行操作,即可显示你的表

  3. Arduino+ESP32 之 驱动GC9A01圆形LCD(二),移植LVGL,跑示例程序,显示自制图片

    在前文Arduino+ESP32 之 驱动GC9A01圆形LCD(一), 我们已经移植好了arduino GFX库, 该库的示例程序内,还有LVGL的示例程序哦. arduino环境下移植lvgl是很 ...

  4. 一次SQL查询优化原理分析(900W+数据,从17s到300ms) (转)

    有一张财务流水表,未分库分表,目前的数据量为9555695,分页查询使用到了limit,优化之前的查询耗时16 s 938 ms (execution: 16 s 831 ms, fetching: ...

  5. bom案例6-轮播图

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. AttributeText创建多彩文字Label --- hl

    一般用富文本实现多种花样的Label文字,下图是利用UILabel分类快速创建的多彩多样lable文字,快速简单,自定义性强,更重要的是无代码污染,特别适合轻量级使用 https://github.c ...

  7. iOS加载Gif图片的N种方式 By-H罗

    1.系统UIImageView 多张图片组成动画 /** * UIImageView 动画 * Memory-23M */ -(void)gifPlay1 { // NSArray *array=@[ ...

  8. Charles抓包工具介绍

    1.Charles是什么? Charles是一款基于http协议的代理服务器,通过称为电脑或者浏览器的代理,然后截取请求和请求结果达到分析抓包的目的. 2.Charles有哪些用途? (1)能够分析前 ...

  9. MySQL高级篇笔记

    目录 MySQL体系结构 存储引擎特点 InnoDB底层文件 MyISAM底层文件 索引 慢查询日志 profile详情 explain执行计划 EXPLAIN 执行计划各字段含义: 索引使用 最左前 ...

  10. Spring Security探究之路之开始

    前言 在Spring Security介绍中,我们分析到了根据请求获取匹配的SecurityFilterChain,这个类中包含了一组Filter 接下来我们从这些Filter开始探究之旅 Sprin ...