分析

好像官方题解是反向求解的,这里提供一个正向求解的思路,即直接求出最后所有叶节点到根的距离相同为 \(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的更多相关文章

  1. [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 ...

  2. 814-Binary Tree Pruning

    Description: We are given the head node root of a binary tree, where additionally every node’s value ...

  3. [LeetCode] Binary Tree Pruning 二叉树修剪

    We are given the head node root of a binary tree, where additionally every node's value is either a ...

  4. Leetcode 814. Binary Tree Pruning

    dfs 要点是这一句: return node.val==1 or node.left or node.right 完整代码: # Definition for a binary tree node. ...

  5. 814. Binary Tree Pruning(leetcode) (tree traverse)

    https://leetcode.com/contest/weekly-contest-79/problems/binary-tree-pruning/ -- 814 from leetcode tr ...

  6. leetcode814 Binary Tree Pruning

    """ We are given the head node root of a binary tree, where additionally every node's ...

  7. 【LeetCode】814. Binary Tree Pruning 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 后序遍历 日期 题目地址:https://leetc ...

  8. LeetCode题解之Binary Tree Pruning

    1.题目描述 2.问题分析 使用递归 3.代码 TreeNode* pruneTree(TreeNode* root) { if (root == NULL) return NULL; prun(ro ...

  9. [Leetcode] Binary Tree Pruning

    題目是說,如果左右子樹都不存在又自已為0,就去掉那個子樹(設為null) recursive後序,左子樹,右子樹,然後是根 自已同時又是別人的子樹,所以要告訢根自已是不是存在 從a開始,左右子樹都不存 ...

  10. 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  ...

随机推荐

  1. 中电金信:亚洲TOP1 霸榜15年

    近日,国际权威语言服务研究机构CSA Research公布了<2022年全球语言服务提供商100强>和<亚太地区TOP 30语言服务商>排名报告. 中电金信凭借卓越的品质管控. ...

  2. MySQL 优化利器 SHOW PROFILE 的实现原理

    背景 最近碰到一个 case,通过可传输表空间的方式导入一个 4GB 大小的表,耗时 13 分钟. 通过PROFILE定位,发现大部分耗时竟然是在System lock阶段. mysql> se ...

  3. 【NAS】绿联NAS UGOS PRO 使用natfrp(Sakura Frp)内网穿透访问Docker应用

    配置加速 https://registry.cn-hongkong.aliyuncs.com 下载镜像 创建容器 [容器]-[创建]-[手动创建]- 选择你下载的镜像即可 在日志中查看密码 访问容器 ...

  4. 2024年1月Java项目开发指南14:关于post中的body和param以及java中的@RequestBody和@RequestParam

    在HTTP请求中,POST方法通常用于向服务器发送数据,这些数据可以在请求的body中,也可以在URL的param中.不过,这两者的使用方式和适用场景是不同的. Body:在POST请求中,body主 ...

  5. How to Use cURL HTTP/2 on macOS

    cURL is one of most powerful tools for testing HTTP traffic. We typically use cURL to interact with ...

  6. Mybatis-plus关于代码生成器的使用

    1.添加依赖 2.在test包下创建一个CodeGet类,实现生成代码的功能.注意:全局配置.数据源配置一定要和自己的电脑配置一致! 3.执行CodeGet类中的main方法.打印台有如下图提示字样, ...

  7. Qt/C++摄像头采集/二维码解析/同时采集多路/图片传输/分辨率帧率可调/自动重连

    一.前言 本地摄像头的采集可以有多种方式,一般本地摄像头会通过USB的方式连接,在嵌入式上可能大部分是CMOS之类的软带的接口,这些都统称本地摄像头,和网络摄像头最大区别就是一个是通过网络来通信,一个 ...

  8. [转]Spring Security打造一个简单Login登录页面,实现登录+跳转+注销+角色权限功能,核心代码不到100行!

    原文链接:Spring Security打造一个简单Login登录页面,实现登录+跳转+注销+角色权限功能,核心代码不到100行!

  9. C# Winform 通过 NAudio 获取控制电脑操作系统音量

    https://github.com/naudio/NAudio NAudio 是一个开源的 .NET 音频库,由 Mark Heath 开发,开源地址:https://github.com/naud ...

  10. VueRouter案列

    案列内容,包含,模板,路由传参,路由重定向,路由嵌套,能够复习路由基本使用,成果如图: 完整代码: 1 <!DOCTYPE html> 2 <html lang="en&q ...