【每日一题】11.黑白树 (树上DFS)
补题链接:Here
题目描述
一棵 \(n\) 个点的有根树,\(1\) 号点为根,相邻的两个节点之间的距离为 \(1\) 。树上每个节点 \(i\)对应一个值\(k[i]\)。每个点都有一个颜色,初始的时候所有点都是白色的。
你需要通过一系列操作使得最终每个点变成黑色。每次操作需要选择一个节点 \(i\) ,\(i\) 必须是白色的,然后 \(i\) 到根的链上(包括节点 \(i\) 与根)所有与节点 \(i\) 距离小于 \(k[i]\) 的点都会变黑,已经是黑的点保持为黑。问最少使用几次操作能把整棵树变黑。
输入描述:
第一行一个整数 \(n\) (\(1 ≤ n ≤ 10^5\) )
接下来 \(n-1\) 行,每行一个整数,依次为 \(2\) 号点到 \(n\) 号点父亲的编号。 最后一行 \(n\) 个整数为 \(k[i] (1 ≤ k[i] ≤ 10^5)\)
样例解释:
对节点 \(3\) 操作,导致节点 \(2\) 与节点 \(3\) 变黑
对节点 \(4\) 操作,导致节点\(4\) 变黑
对节点 \(1\) 操作,导致节点 \(1\) 变黑
输出描述:
一个数表示最少操作次数
示例1
输入
4
1
2
1
1 2 2 1
输出
3
Solution
由题意可知叶子节点必定要染色。对于其他节点:
- 若此节点的已经染色的子节点中,可以将它覆盖,那么不需要染色,并借助这个点能覆盖的范围更新最大范围。
- 若此节点的已经染色的子节点中,不能将它覆盖,那么需要将其子节点中范围最大的点染色,并更新最大范围。
可以发现这是一个由子节点向父节点更新的过程,所以可以使用 \(DFS\) 。每次贪心地更新能覆盖的最大距离,不能覆盖就进行染色。
- 时间复杂度:\(\mathcal{O}(n)\)
const int N = 1e5 + 10;
vector<int>e[N], k(N, 0), f(N, 0);
int ans = 0;
void dfs(int u, int fa) {
for (int i = 0; i < e[u].size(); ++i) {
int v = e[u][i];
dfs(v, u);
f[u] = max(f[u], f[v] - 1); //维护f值——儿子的f值-1之后的最大值
k[u] = max(k[u], k[v] - 1); //维护k值——儿子的k值-1和自己的k值的最大值
}
// cout << f[u] << " " << k[u] << "\n";
//下面的点都覆盖不到它了——选他自己,此时就要更新 f 值
if (f[u] == 0) ++ans, f[u] = k[u];
}
void solve() {
int n;
cin >> n;
for (int i = 2, x; i <= n; ++i) {
cin >> x;
e[x].push_back(i);
}
for (int i = 1; i <= n; ++i) cin >> k[i];
dfs(1, 0);
cout << ans;
}
如果深度理解这道题以后可以直接在solve里写DFS,此时运行速度会快很多 (60ms -> 18ms)
const int N = 1e5 + 10;
void solve() {
int n;
vector<int> p(N), k(N), f(N), g(N, 0);
cin >> n;
for (int i = 2; i <= n; ++i) cin >> p[i];
for (int i = 1; i <= n; ++i) cin >> k[i];
int ans = 0;
for (int i = n; i; --i) {
g[i] = max(g[i], k[i]);
if (f[i] == 0) ++ans, f[i] = g[i], g[i] = 0;
f[p[i]] = max(f[p[i]], f[i] - 1);
g[p[i]] = max(g[p[i]], g[i] - 1);
}
cout << ans << "\n";
}
【每日一题】11.黑白树 (树上DFS)的更多相关文章
- 【每日一题】【树的dfs递归,返回多次,注意都遍历完后才最终返回】2022年1月6日-112. 路径总和
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum .判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum .如果存在,返回 tr ...
- CodeM美团点评编程大赛初赛B轮 黑白树【DFS深搜+暴力】
[编程题] 黑白树 时间限制:1秒 空间限制:32768K 一棵n个点的有根树,1号点为根,相邻的两个节点之间的距离为1.树上每个节点i对应一个值k[i].每个点都有一个颜色,初始的时候所有点都是白色 ...
- CISP/CISA 每日一题 11
CISA 每日一题(答) 一个合理建造的数据仓库应当支持下列三种基本的查询格式: 1.向上溯源和向下溯源——向上溯源是对数据进行总计:向下溯源是将数据进行细化: 2.交叉溯源——通过通用属性访问数据仓 ...
- java面试每日一题11
题目:求1+2!+3!+...+20!的和 public class Recursion { public static void main(String args[]) throws NumberF ...
- 【js】Leetcode每日一题-叶子相似的树
[js]Leetcode每日一题-叶子相似的树 [题目描述] 请考虑一棵二叉树上所有的叶子,这些叶子的值按从左到右的顺序排列形成一个 叶值序列 . 举个例子,如上图所示,给定一棵叶值序列为 (6, 7 ...
- uoj #139. 【UER #4】被删除的黑白树 dfs序 贪心
#139. [UER #4]被删除的黑白树 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/139 Descript ...
- 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)
牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...
- 【python】Leetcode每日一题-前缀树(Trie)
[python]Leetcode每日一题-前缀树(Trie) [题目描述] Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的 ...
- [每日一题2020.06.08]洛谷P1605 DFS
今天cf又杯具的只写出2题, 虽然AB题20分钟左右就搞定了, 但是CD写了2个小时也没写出来 D题我用到了DFS, 虽然必不正确, 但是我至少发现了一个问题, 那就是我连DFS都忘了, 于是怒找DF ...
- [BZOJ 3319] 黑白树
3319: 黑白树 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 557 Solved: 194[Submit][Status][Discuss] ...
随机推荐
- [ABC274E] Booster
Problem Statement In a two-dimensional plane, there are $N$ towns and $M$ chests. Town $i$ is at the ...
- 使用Visual Studio 2022 创建lib和dll并使用
对于一个经常写javaWeb的人来说,使用Visual Studio似乎没什么必要,但是对于使用ffi的人来说,使用c或c++编译器,似乎是必不可少的,下面我将讲述如何用Visual Studio 2 ...
- 13 HTTP传输大文件的方法
目录 如何在有限的带宽下高效快捷传输大文件? 数据压缩 分块传输 范围请求 多段数据 如何在有限的带宽下高效快捷传输大文件? 数据压缩 分块传输 范围请求 多段数据 数据压缩 思路:把大文件整体变小 ...
- jextract的使用
写这个博客的目的:新人去看jextract的官网是看不懂的,就算看懂了也不会使用,一头雾水,我会从0开始教如何使用,如何搭配java去调用c函数. 首先我们得了解jextract是什么,官网的解释是一 ...
- Go 语言为什么很少使用数组?
大家好,我是 frank,「Golang 语言开发栈」公众号作者. 01 介绍 在 Go 语言中,数组是一块连续的内存,数组不可以扩容,数组在作为参数传递时,属于值传递. 数组的长度和类型共同决定数组 ...
- Ubuntu基线指导手册
Ubuntu基线指导手册 1. 身份鉴别策略组检测 准备: 安装一个PAM模块来启用cracklib支持,这可以提供额外的密码检查功能. 在Debian,Ubuntu或者Linux Mint使用命 ...
- OpenSSL命令总结
OpenSSL命令总结 疑今者察之古,不知来者视之往. 导航 介绍 对称加密 公钥加密 信息摘要 数字证书 杂项 介绍 密码学标准和互联网协议一样,是一种大家都遵守的约定和标准,比如PKCS#1中规定 ...
- JPA复杂查询时间查询分页排序
JPA复杂查询时间查询分页排序 JPA复杂查询时间查询分页排序,工作上用到,因为项目是jpa,记录.代码囊括了:查询条件+时间范围+分页+排序 其实我也不太想用jpa,但是他也有优点,操作可以兼容多种 ...
- 快速批量升级 NugetPackage 版本
批量升级项目中的 Nuget 有时候我们需要升级整个解决方案中的某些Nuget版本,如果每个手动使用NuGet Package Manager 会很麻烦.经过一个周末的踩坑,我找到一个解决方案. Na ...
- 我用 Laf 开发了一个非常好用的密码管理工具
[KeePass 密码管理]是一款简单.安全简洁的账号密码管理工具,服务端使用 Laf 云开发,支持指纹验证.FaceID,N 重安全保障,可以随时随地记录我的账号和密码. 写这个小程序之前,在国内市 ...