1. 问题背景与核心概念解析
今天我们来探讨一个有趣的图论问题——如何计算树结构中每个节点所在连通子图的最大得分。这个问题来自力扣第3772题,考察了我们对树结构的理解和动态规划的应用能力。
首先明确几个关键概念:
- 无向树:由n个节点和n-1条边组成的连通无向图,任意两个节点之间有且只有一条路径。
- 好节点与坏节点:每个节点被标记为good[i]=1(好节点)或good[i]=0(坏节点)。
- 子图得分:子图中好节点数量减去坏节点数量。例如,子图包含3个好节点和1个坏节点,得分为3-1=2。
问题的核心要求是:对于树中的每个节点i,找出所有包含i的连通子图中可能的最大得分。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 暴力解法与性能瓶颈分析
最直观的解法是枚举所有可能的连通子图:
- 对于每个节点i,进行DFS/BFS遍历
- 在遍历过程中记录所有连通子图的得分
- 选择包含i的子图中的最大得分
但这种暴力解法的时间复杂度高达O(n²),当n=10^5时完全不可行。我们需要更聪明的算法。
提示:在树结构中,当遇到O(n²)解法时,通常可以考虑使用动态规划或换根法来优化到O(n)。
3. 换根法原理详解
换根法(Rerooting Technique)是一种处理树形结构的高效算法,核心思想是通过两次DFS遍历:
- 第一次DFS(后序遍历):以任意节点(如0)为根,计算每个节点不考虑父节点方向的最大得分(sub[i])
- 第二次DFS(前序遍历):利用父节点的信息,计算考虑全树情况下的最终答案(ans[i])
3.1 关键定义与性质
定义:
sub[i]:以i为根的子树中,包含i但不考虑父节点方向的最大得分ans[i]:全树范围内包含i的最大得分
性质:
sub[i] = good[i] + Σ max(0, sub[j]),其中j是i的子节点- 只累加正数子节点,因为负数会降低总分
ans[root] = sub[root](根节点没有父节点)- 对于非根节点cur,其父节点为par:
- 如果
sub[cur] > 0,则父方向得分为ans[par] - sub[cur] - 否则为
ans[par]
- 如果
