📅  最后修改于: 2023-12-03 15:40:27.113000             🧑  作者: Mango
本文主要介绍树上动态规划算法的套件,使用该套件可以解决一系列树上动态规划问题。
在使用该套件之前,你需要掌握以下知识:
该套件包含以下算法:
树的重心是指树中某个节点,如果把该节点和它的子树删除,剩余子树的节点数最大。
def get_centroid(u, p, sz, w):
for v in w[u]:
if v != p:
get_centroid(v, u, sz, w)
sz[u] += sz[v]
mx = max(sz[v] for v in w[u] if v != p)
if max(mx, len(w) - sz[u]) <= len(w) // 2:
return u
树的直径是指树中最长的路径。
def get_diameter(u, p, d, w):
dia = [d[u], 0]
for v in w[u]:
if v != p:
res = get_diameter(v, u, d + 1, w)
dia = max(dia, res, key=lambda x: x + 1)
return dia
树的深度是指从根节点到每个节点的路径长度。
def get_depths(u, p, d, dp, w):
dp[u] = d
for v in w[u]:
if v != p:
get_depths(v, u, d + 1, dp, w)
树的直径路径即为树的直径所连接的两个节点之间的路径。
def get_diameter_path(u, p, d, w):
res = [(u, d)]
for v in w[u]:
if v != p:
res = max(res, get_diameter_path(v, u, d + 1, w), key=lambda x: x[1])
return res if p is not None else res[:-1]
LCA是指两个节点的最近公共祖先。
def get_lca(u, v, p, dp, w):
while dp[u] > dp[v]:
u, v = v, u
while dp[u] < dp[v]:
v = p[v]
while u != v:
u, v = p[u], p[v]
return u
树的节点独立集是指树中最大独立节点集合。
def get_maximum_independent_set(u, p, dp, dp1, dp2, w):
dp1[u] = 1
dp2[u] = 0
for v in w[u]:
if v != p:
get_maximum_independent_set(v, u, dp, dp2, dp1, w)
dp1[u] += dp2[v]
dp2[u] += max(dp1[v], dp2[v])
树上动态规划是一类常见的问题,常常需要使用到一些套装算法,如本文中介绍的树的重心、树的直径、树的深度、树的直径路径、LCA和树的节点独立集算法,它们可以很好地应用于处理树上的问题。