换根 DP 简介

news/2026/1/20 21:34:36/文章来源:https://www.cnblogs.com/triwa/p/19508854

【换根 DP 简介】
● 换根 DP 是树形 DP 的一种重要技术,用于解决需要以树中‌不同节点为根‌分别计算答案的问题。其核心思想是在一次动态规划后,通过‌推导出换根时的状态转移公式‌,高效地计算出所有节点作为根时的结果,避免对每个根节点都进行一次 O(n) 的树形DP(那样总复杂度为 O(n²))。

● 对于大多数简单的树形 DP 问题,如计算子树大小、节点深度、简单路径统计等,算法通常对每个节点执行常数次操作,因此时间复杂度为 ‌O(n)‌。

● 换根 DP 通常遵循一个固定的两遍 DFS 流程:
(一)第一次 DFS(固定根,收集信息)‌
(1)任选一个节点(通常为 1 号节点)作为初始根。
(2)进行一次自底向上的树形 DP,计算以该节点为根时,各子树的状态信息。这些信息通常包括:子树大小(siz[u])、子树内节点到根的距离和(dis[u])、或其他与问题相关的子树最优解。
(二)第二次 DFS(换根,推导全局)‌
(1)这是算法的关键。基于第一次 DFS 得到的信息,从初始根节点开始,进行第二次 DFS。
(2)在遍历过程中,当从父节点 u 走向子节点 v 时,利用已知的以 u 为根时的全局答案 dp[u],推导出以 v 为根时的全局答案 dp[v]。
(3)这个推导过程就是 ‌“换根公式”‌,它分析了当根从 u 移到 v 时,哪些节点的贡献发生了变化(例如,深度增加或减少),并据此更新答案。

● 经典示例:所有节点到其他节点距离之和
代码详见:https://blog.csdn.net/hnjzsyjyj/article/details/157169859
这是一个最经典的换根DP问题,清晰地展示了换根公式的推导过程。
(1)问题‌:给一棵树,求以每个节点为根时,所有节点到该根节点的深度之和。
(2)定义‌:siz[u]:以 u 为根的子树中的节点数、dis[u]:以 u 为根时,所有节点到 u 的深度之和。

P3478_1

(3)步骤‌:
第一次 DFS‌:以节点 1 为根,计算 siz[u] 和初始的 dis[1]。
换根公式推导‌:当根从 u 换到其子节点 v 时,所有在 v 子树中的节点,到新根 v 的距离比到旧根 u 的距离‌减少1‌。这部分贡献总共减少 siz[v]。所有不在 v 子树中的节点(共 n - siz[v] 个),到新根 v 的距离比到旧根 u 的距离‌增加1‌。这部分贡献总共增加 n - siz[v]。
因此,dis[v] = dis[u] - siz[v] + (n - siz[v]) = dis[u] + n - 2 * siz[v]。
第二次 DFS‌:应用此公式,即可从 dp[1] 递推计算出所有节点的 dis[i]。

● 换根 DP 问题的数据量通常会超过 10^5,所以常需在代码中使用如下语句(https://blog.csdn.net/hnjzsyjyj/article/details/143176072),避免 TLE。

ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);

当然,也可以使用“快读(https://blog.csdn.net/hnjzsyjyj/article/details/120131534)”函数,代码如下。

int read() { //fast readint x=0,f=1;char c=getchar();while(c<'0' || c>'9') { //!isdigit(c)if(c=='-') f=-1;c=getchar();}while(c>='0' && c<='9') { //isdigit(c)x=x*10+c-'0';c=getchar();}return x*f;
}


【换根 DP 的经典问题】
洛谷 P3478:STA-Station:https://blog.csdn.net/hnjzsyjyj/article/details/157169859
洛谷 P10962:Computer:https://blog.csdn.net/hnjzsyjyj/article/details/157177019
洛谷 P6419:Kamp:https://blog.csdn.net/hnjzsyjyj/article/details/157134513

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1190866.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文字标注旋转角度设置(防止文字倒立)

对CAD中曲线进行文字标记时&#xff0c;当文字角度必须随曲线角度时&#xff0c;为避免字头朝下&#xff0c;可采用如下方式ang ang % Math.PI;while (ang < 0) { ang Math.PI; }// 确保文字不会倒立&#xff08;阅读方向从左到右&#xff09;while (ang > Math.PI / 2…

【毕业设计】基于机器学习的网络购物平台的智能推荐(源码+文档+远程调试,全bao定制等)

java毕业设计-基于springboot的(源码LW部署文档全bao远程调试代码讲解等) 博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、…

储能辅助电力系统调峰的容量需求研究 Matlab代码

✅作者简介&#xff1a;热爱数据处理、建模、算法设计的Matlab仿真开发者。&#x1f34e;更多Matlab代码及仿真咨询内容点击 &#x1f517;&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码获取及仿真咨询内容私信。&#x1f447; 关注我…

咋的,寒假 1 个月学门黑客技术,难道很难吗?

前言 先介绍一下我自己吧&#xff0c;我是一名从事网络安全行业近十年的白帽黑客&#xff0c;在奇安信做了6年的安全研发员&#xff0c;期间大大小小的Hvv也参加了数次&#xff0c;都取得了不错的成绩。本文我就以亲身经验为锚&#xff0c;给那些有着一个黑客梦的小伙伴撰写一份…

【Matlab】 CRC-8 计算数组Checknum

function crc crc8(data) % data: uint8 数组 poly uint8(hex2dec(07)); % 多项式 crc uint8(0); % 初始值for byte datacrc bitxor(crc, byte); % 与输入异或for i 1:8if bitand(crc, 128) % 检查最高位crc bitxor(bitshift(crc, 1), poly);elsecrc bitshift(crc, 1);…

拒绝“数据搬运工”:PostgreSQL 存储过程与函数实战指南

后端兄弟别当搬运工!10行代码省下50%网络开销 快停手,你的 Java/Python 代码正在“谋杀”数据库! 实测数据显示,同样的批量处理逻辑,放在应用层跑比原生数据库慢了整整 10 倍。 连 Stack Overflow 上的高赞回答都直言:“把逻辑离数据近一点,是高性能架构的第一铁律。” …

2026年评价高的镀锌桥架,模压桥架,北方电缆桥架厂家行业优质推荐 - 品牌鉴赏师

引言在现代基础设施建设中,电缆桥架作为电缆敷设的重要支撑和保护装置,其质量和性能直接关系到电力系统的安全稳定运行。为了帮助广大用户在众多电缆桥架厂家中挑选出最优质、最适合的合作伙伴,我们依据一系列科学、…

吐血推荐!本科生AI论文平台TOP10:开题报告文献综述全搞定

吐血推荐&#xff01;本科生AI论文平台TOP10&#xff1a;开题报告文献综述全搞定 2026年本科生AI论文平台测评&#xff1a;为什么你需要这份榜单&#xff1f; 随着人工智能技术的不断进步&#xff0c;越来越多的本科生开始借助AI工具辅助论文写作。然而&#xff0c;面对市场上五…

开源版 Claude Code 杀疯了,怒斩 70k+ Star!!

大家好,我是R哥。 前段时间分享了《2026 AI编程终极套装:Claude Code + Codex + Gemini CLI + Antigravity,四位一体实战指南!!》,还没来得及学习? 别急,2026 年 AI 编程工具又要变天了。。 最近一款号称开源版…

Jetbrains全家桶自动破解

1.下载需要的pycharm与idea等 打开网站查看破解命令 https://liyangxu1.github.io/keyrun/ 2.打开powershell 3.输入: 对应的命令 一路回车即可 Linux: Mac:

UVM-build_phase/run_phase的执行顺序及仿真调度

build_phase build_phase的执行顺序在整个层次上看遵循从上到下,但在一个组件内中的build_phase是顺序顺序执行。create的本质就是创建对象,本质是调用new函数。所以在build_phase中呈现的顺序会出现跳转现象。当在build_phase中执行到create函数时,它会去执行所要创建的组件…

AL_ControlRes代码中文注释

///////////////////////////////////////////////////////////////////////////////////////// /*** \brief 应用程序控制响应函数 (Application Control Response)。* \details 此函数由协议栈周期性地调用&#xff0c;用于处理由应用程序触发的、需要异步完成的状态转换…

Makefile中 =、:=和 ?=的使用方法

理解Makefile中 、:和 ?这三个赋值操作符的区别&#xff0c;对编写可靠高效的构建脚本至关重要。下面这个表格能帮你快速把握它们的核心差异。特性(递归扩展赋值):(简单扩展赋值)?(条件赋值)赋值时机​变量被使用&#xff08;引用&#xff09;时才展开求值变量定义时就立即展…

2026.1.10 作业 - # P14063 [PO Final 2022] 海滩 / Badstrand

2026.1.10 作业 - # P14063 [PO Final 2022] 海滩 / Badstrand题目描述 Maja 厌倦了海岸被大湖占据,她想要修建一个又长又漂亮的公用海滩。现在,她计划买下海岸边的一块土地来建造海滩。 Maja 预算为 \(B\) 克朗。有…

AndroidStudio汉化步骤

代码视图切换按钮&#xff1a;

突破AI产品经理求职难关:技术认知、产品思维与落地能力三大必修课

文章介绍了AI产品经理必备的三大核心能力&#xff1a;技术直觉与认知边界&#xff08;理解技术基础概念和边界&#xff09;、AI产品感&#xff08;从用户真实需求出发创造价值&#xff09;、AI产品的落地与评估&#xff08;具备落地经验和科学评估方法&#xff09;。优秀的AI产…

基于模块化设计的可定制多领域推理系统

基于模块化设计的可定制多领域推理系统 关键词:模块化设计、可定制、多领域推理系统、推理算法、应用场景 摘要:本文围绕基于模块化设计的可定制多领域推理系统展开深入探讨。首先介绍了该系统的背景,包括目的、预期读者、文档结构和相关术语。接着阐述了核心概念与联系,给…

C++ 线程互斥锁 lock_guard

std::lock_guard是 C11 标准库提供的RAII 风格的互斥锁封装类&#xff0c;核心目的是自动管理互斥锁的加锁 / 解锁&#xff0c;从根本上避免 “忘记解锁导致死锁”“异常导致锁无法释放” 这类低级且致命的错误。一、先理解核心&#xff1a;RAII 设计思想lock_guard的底层是RAI…

大模型应用工程师崛起之路:从入门到年薪60万+的完整指南

本文全面解析大模型应用工程师职业&#xff0c;介绍其定义、职责及广阔就业前景。数据显示该岗位70.8%月薪达20K-50K&#xff0c;年薪24-60万。文章提供系统学习路径&#xff0c;包括Python入门、大模型核心原理、Transformer架构、微调技术及企业级实战项目。职业发展可走技术…

人工智能应用-机器视觉:绘画大师 04.​​​​​​​​​​​​​​基于风格迁移的绘画大师

利用深度神经网络的这种内容&#xff0d;风格分离能力可以实现图片的风格迁移&#xff0c;即将一张图片 B 的风格迁移到另一张图片 A 上。换句话说&#xff0c;就是希望得到一张图片&#xff0c;该图片在内容上与 A 一致&#xff0c;但在风格上与 B 一致。实现这一目标的方法如…