标记所有节点需要的时间
简单来说给一张有向图,找到每个节点的最大深度
找到一个节点的最大深度时,我们可以用一个简单的DFS
,如果是每一个节点,需要用到DP
第一次dfs
,找到每个节点向下的最大深度max_d
,次大深度深度max_d2
,最大深度节点的id
,max_son_id
第二次dfs
,为每个节点进行挑选,是选择往下走的最大深度呢,还是选择往上走的最大深度呢
from_up
是个很重要的参数,他代表往上走的最大深度,当往下递归的时候,需要更新。父亲走到儿子,那么此时就应该以儿子为中心了,儿子往下的最大深度已经算出不用管了,来自父亲的最大深度需要更新,因为往上走的最大深度有可能来自父亲的父亲,也有可能来自父亲的儿子,即拐一个弯
class Solution:
def timeTaken(self, edges: List[List[int]]) -> List[int]:
g = [ [] for _ in range(len(edges) + 1) ]
for x , y in edges:
g[x].append(y)
g[y].append(x)
nodes = [None ]* len(g)
def dfs(u:int, fa:int)->int:
max_d = max_d2 = max_son_id = 0
for j in g[u]:
if j == fa:
continue
depth = dfs(j, u) + (j + 1) % 2 + 1
if depth > max_d:
max_d2 = max_d
max_d = depth
max_son_id = j
elif depth > max_d2:
max_d2 = depth
nodes[u] = (max_d,max_d2, max_son_id)
return max_d
dfs(0, -1)
ans = [0] * len(g)
print(nodes)
def reroot(u:int, fa:int, from_up:int) -> None:
max_d, max_d2, max_son_id = nodes[u]
ans[u] = max(from_up, max_d)
for j in g[u]:
if j == fa:continue
up1 = from_up
up2 = (max_d2 if j == max_son_id else max_d)
# from_up也有两类,一类是还是父亲的from_up,另一类是父亲中儿子最出色的
reroot(j, u, max(up1, up2) + (u + 1) % 2 + 1 )
reroot(0, -1, 0)
return ans