1 条题解
-
0
19220448 董文杰 (董文杰) LV 9 @ 1 年前
算法:换根dp | BFS
题意:给定一棵树,现在需要选择其中的一个结点为根节点,使得深度和最大。深度的定义是以每个结点到树根所经历的结点数
思路:
暴力:
- 显然可以直接遍历每一个结点,计算每个结点的深度和,然后取最大值即可
- 时间复杂度:
优化:
先看图:
我们可以发现,对于当前的根结点
fa
,我们选择其中的一个子结点ch
,将ch
作为新的根结点(如右图)。那么对于当前的ch
的深度和,我们可以借助fa
的深度和进行求解。我们假设以ch
为子树的结点总数为x
,那么这x
个结点在换根之后,相对于ch
的深度和,贡献了-x
的深度;而对于fa
的剩下来的n-x
个结点,相对于ch
的深度和,贡献了n-x
的深度。于是ch
的深度和就是fa的深度和
-x+n-x
,即
dep[ch] = dep[fa]-x+n-x = dep[fa]+n-2*x
于是我们很快就能想到利用前后层的递推关系, 的计算出所有子结点的深度和代码实现:我们可以先计算出
base
的情况,即任选一个结点作为根结点,然后基于此进行迭代计算。在迭代计算的时候需要注意的点就是在一遍dfs
计算某个结点的深度和dep[root]
时,如果希望同时计算出每一个结点作为子树时,子树的结点数,显然需要分治计算一波。关于分治的计算我熟练度不够高,~~特此标注一下debug了3h的点~~:即在递归到最底层,进行回溯计算的时候,需要注意不能统计父结点的结点值(因为建的是双向图,所以一定会有从父结点回溯的情况),那么为了避开这个点,就需要在 的时间复杂度内获得当前结点的父结点的编号,从而进行特判,采用的方式就是增加递归参数fa
。没有考虑从父结点回溯的情况的dfs代码
考虑了从父结点回溯的情况的dfs代码
时间复杂度:
暴力代码:
优化代码:
- 1
信息
- ID
- 1534
- 难度
- 7
- 分类
- (无)
- 标签
- (无)
- 递交数
- 25
- 已通过
- 6
- 通过率
- 24%
- 上传者