CF2018C Tree Pruning
分析
好像官方题解是反向求解的,这里提供一个正向求解的思路,即直接求出最后所有叶节点到根的距离相同为 \(x\) 时需要删除的结点数 \(ans_x\) 。
如果我们最后到根的相同距离为 \(x\),那么答案有两个组成部分。
第一个部分,若到根距离为 \(x\) 的结点是一个中间结点,也就是说这个结点还有子节点,那么直接把比这个点更深的子树都删掉即可。
第二个部分,对于每一个分枝,若这个分支的最深深度小于 \(x\) ,那么这一整个分支都得删掉。因为这个分枝只要有剩余,它的叶节点到根的距离一定小于 \(x\) 。只有被完全剪掉,才会不剩余叶节点,才会没有到根距离小于 \(x\) 的叶节点。
因此,我们只需要处理出所有剪完后叶节点到根的距离的删减数,再所有答案取最小就行了,而这个过程,也只需要一次 DFS 就能完成。
对于第一个部分,只需要在 DFS 的过程维护一下下方子树的大小,在每一层加上所有下方子树大小即可。
对于第二个部分,对于每一个点,我们记录一下这个点所代表的子树的最深深度,那么想一下,是不是只要最后要保留的叶节点到根的距离大于这个结点的深度,这个结点就得被删掉。
所以,我们可以用 差分数组 来维护这一件事。
记 \(mx_i\) 为结点 \(i\) 的子树的最深深度,\(z\) 数组是第二部分的答案数组的差分数组,因此每一个点对第二部分的答案数组贡献就是对 \(z_{mx_i + 1} + 1\) 。
最后,把两部分的答案加一下就行了,然后对所有情况的答案取最小即可。
上代码!
AC CODE
#include <bits/stdc++.h>
#define int long long
#define inf INT64_MAX
#define ull unsigned long long
using namespace std;
const int N = 6e5 + 9;
int d[N], k[N], sz[N], z[N];
//d:当前结点深度 k:保留的距离要减掉的结点数 sz:当前结点代表的子树大小 z:第二部分答案的差分数组
int mx[N];//当前结点最深深度
int dmx;
vector<int> g[N];
void dfs(int st, int pre)//st:当前结点 pre:父节点
{
if(st != 1)d[st] = d[pre] + 1;
dmx = max(dmx, d[st]);//求出整棵树的最深深度
sz[st] = 1;
if(g[st].size() == 1 && st != 1)
{
mx[st] = d[st];
}
for(auto &i : g[st])
{
if(i == pre)continue;
dfs(i, st);
k[d[st]] += sz[i];//第一部分答案
sz[st] += sz[i];
mx[st] = max(mx[st], mx[i]);
}
if(st != 1)z[mx[st] + 1] ++;//给第二部分答案做贡献
}
void init(int n)
{
for(int i = 1;i <= n + 10;i ++)
{
g[i].clear();
k[i] = 0;
sz[i] = 0;
z[i] = 0;
mx[i] = 0;
}
dmx = 0;
}
void solve()
{
int n;cin >> n;
init(n);
for(int i = 1;i < n;i ++)
{
int u, v;cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
d[1] = 0;
dfs(1, -1);
for(int i = 1;i <= dmx;i ++)z[i] += z[i - 1];//差分数组前缀和求出第二部分的答案
for(int i = 1;i <= dmx;i ++)k[i] += z[i];//两部分答案求和
int ans = inf;
for(int i = 1;i <= dmx;i ++)ans = min(ans, k[i]);
cout << ans << '\n';
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t = 1;cin >> t;
while(t --)solve();
return 0;
}
CF2018C Tree Pruning的更多相关文章
- [Swift]LeetCode814. 二叉树剪枝 | Binary Tree Pruning
We are given the head node root of a binary tree, where additionally every node's value is either a ...
- 814-Binary Tree Pruning
Description: We are given the head node root of a binary tree, where additionally every node’s value ...
- [LeetCode] Binary Tree Pruning 二叉树修剪
We are given the head node root of a binary tree, where additionally every node's value is either a ...
- Leetcode 814. Binary Tree Pruning
dfs 要点是这一句: return node.val==1 or node.left or node.right 完整代码: # Definition for a binary tree node. ...
- 814. Binary Tree Pruning(leetcode) (tree traverse)
https://leetcode.com/contest/weekly-contest-79/problems/binary-tree-pruning/ -- 814 from leetcode tr ...
- leetcode814 Binary Tree Pruning
""" We are given the head node root of a binary tree, where additionally every node's ...
- 【LeetCode】814. Binary Tree Pruning 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 后序遍历 日期 题目地址:https://leetc ...
- LeetCode题解之Binary Tree Pruning
1.题目描述 2.问题分析 使用递归 3.代码 TreeNode* pruneTree(TreeNode* root) { if (root == NULL) return NULL; prun(ro ...
- [Leetcode] Binary Tree Pruning
題目是說,如果左右子樹都不存在又自已為0,就去掉那個子樹(設為null) recursive後序,左子樹,右子樹,然後是根 自已同時又是別人的子樹,所以要告訢根自已是不是存在 從a開始,左右子樹都不存 ...
- A Complete Tutorial on Tree Based Modeling from Scratch (in R & Python)
A Complete Tutorial on Tree Based Modeling from Scratch (in R & Python) MACHINE LEARNING PYTHON ...
随机推荐
- ThreeJs-07操控物体实现家具编辑器
本章节实现效果,通过gui快速添加场景,家具,并且可以快速设置家具实现一个编辑器效果 一.基础设置与物体添加列表 用之前做过的一个案例来改 首先不要这个模型,然后换个背景颜色,并且添加一个网格辅助器 ...
- opencv+Linux源码编译安装及引用
(一)下载 opencv下载地址:https://opencv.org/releases/ opencv_contrib下载地址:https://github.com/opencv/opencv_co ...
- 深入理解二叉查找树(BST)的重要查找操作
二叉查找树 (Binary Search Tree, 简称 BST) 是一种基本的数据结构,其设计核心在于每个节点的值都满足以下性质: 左子树的所有节点值均小于当前节点值. 右子树的所有节点值均大于当 ...
- 关于Qt数据库相关开发的一些经验总结
一.前言 近期花了两个多月时间,将数据库相关的代码重新封装成了各种轮子(这条路必须打通,打通以后,相关项目只需要引入这个组件pri即可),测试了从Qt4.7到Qt6.1的各种版本,测试了odbc.sq ...
- 『AutoHotkey』 效率提升「脚本集」
AutoHotkey 效率提升脚本集 一些实用的 AutoHotkey 脚本示例,这些可以显著提升工作效率. #Requires AutoHotkey v2.0 ; 1. 快速启动常用程序 ^!n:: ...
- 永远不要轻易设置Oracle的隐藏参数,哪怕是DRM
这篇文章可能会存在较大争议,甚至颠覆一些人的固有思维. 因为关于Oracle的隐藏参数,江湖上一直都有两派对立的观点: 1.不要设置任何隐藏参数,只有当遇到特殊问题时在售后指导下临时使用,在问题解决后 ...
- WPF 查找大小相同文件/图片
假设文件大小一样就表示文件一模一样,是重复文件 using System; using System.Collections.Generic; using System.Linq; using Sys ...
- SpringBoot+SpringSecurity+JWT整合实现单点登录SSO史上最全详解
一.什么是单点登陆 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用 ...
- RocketMQ的架构设计、关键特性、与应用场景详解
内容大纲: 1.RocketMQ的简介与演进 2. RocketMQ的架构设计 3.RocketMQ的关键特性 4.RocketMQ的应用场景 RocketMQ的简介 RocketMQ一个纯java. ...
- G1原理—7.G1的GC日志分析解读
大纲 1.TLAB的GC日志解读 2.YGC的GC日志解读 3.模拟YGC(单次GC及多次GC的不同场景) 4.打开实验选项查看YGC的详情日志信息 5.Mixed GC日志信息之初始标记过程 6.M ...