补题链接: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)的更多相关文章

  1. 【每日一题】【树的dfs递归,返回多次,注意都遍历完后才最终返回】2022年1月6日-112. 路径总和

    给你二叉树的根节点 root 和一个表示目标和的整数 targetSum .判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum .如果存在,返回 tr ...

  2. CodeM美团点评编程大赛初赛B轮 黑白树【DFS深搜+暴力】

    [编程题] 黑白树 时间限制:1秒 空间限制:32768K 一棵n个点的有根树,1号点为根,相邻的两个节点之间的距离为1.树上每个节点i对应一个值k[i].每个点都有一个颜色,初始的时候所有点都是白色 ...

  3. CISP/CISA 每日一题 11

    CISA 每日一题(答) 一个合理建造的数据仓库应当支持下列三种基本的查询格式: 1.向上溯源和向下溯源——向上溯源是对数据进行总计:向下溯源是将数据进行细化: 2.交叉溯源——通过通用属性访问数据仓 ...

  4. java面试每日一题11

    题目:求1+2!+3!+...+20!的和 public class Recursion { public static void main(String args[]) throws NumberF ...

  5. 【js】Leetcode每日一题-叶子相似的树

    [js]Leetcode每日一题-叶子相似的树 [题目描述] 请考虑一棵二叉树上所有的叶子,这些叶子的值按从左到右的顺序排列形成一个 叶值序列 . 举个例子,如上图所示,给定一棵叶值序列为 (6, 7 ...

  6. uoj #139. 【UER #4】被删除的黑白树 dfs序 贪心

    #139. [UER #4]被删除的黑白树 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/139 Descript ...

  7. 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)

    牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...

  8. 【python】Leetcode每日一题-前缀树(Trie)

    [python]Leetcode每日一题-前缀树(Trie) [题目描述] Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的 ...

  9. [每日一题2020.06.08]洛谷P1605 DFS

    今天cf又杯具的只写出2题, 虽然AB题20分钟左右就搞定了, 但是CD写了2个小时也没写出来 D题我用到了DFS, 虽然必不正确, 但是我至少发现了一个问题, 那就是我连DFS都忘了, 于是怒找DF ...

  10. [BZOJ 3319] 黑白树

    3319: 黑白树 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 557  Solved: 194[Submit][Status][Discuss] ...

随机推荐

  1. 《HelloGitHub》第 92 期

    兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...

  2. jmeter-json断言

    1.JSON 断言所在位置:断言->JSON 断言 2.JSON断言中的字段解析 Assert JSON Path exists:json 表达式,判断所字段是否存在,存在则为True, 否则为 ...

  3. java-生成二维码/条形码

    前言:   需求:生成二维码/条形码 //使用ZXing库 <dependencies> <dependency> <groupId>com.google.zxin ...

  4. java-EasyExcel模板导出

    前言:  需求:根据自定义模板导出Excel,包含图片.表格,采用EasyExcel 提示:EasyExcel请使用 3.0 以上版本, 对图片操作最重要的类就是 WriteCellData<V ...

  5. HBase应用方案

    HBase性能优化方法:

  6. python 获取apk 信息

    python 获取apk 信息 1.安装androguard pip install androguard 2.获取apk的相关信息 引入基础信息 from androguard.misc impor ...

  7. C++ Qt开发:SqlTableModel映射组件应用

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍SqlTabl ...

  8. tty详解

    linux下tty命令详解 [功能] 打印连接到标准输入的终端的文件名. [描述] 命令项: -s, --silent, --quiet: 什么也不打印,只是返回退出状态码. --help: 打印帮助 ...

  9. 解决 cv2.destroyAllWindows() 无效问题

    方法一 示例代码: import cv2 import numpy as npimg = np.zeros((512,512),np.uint8)#生成一个空灰度图像 cv2.line(img,(0, ...

  10. Kafka 万字精讲|工作五年这些你都知道吗?

    目录 前言 一.Kafka 简介 1.1 事件流平台 1.2 Kafka 主要概念和术语 1.3 Zookeeper 二.Kafka 集群搭建和使用 2.1 使用 Docker Compose 搭建 ...