LC 3367. 移除边之后的权重最大和
https://leetcode.cn/problems/maximize-sum-of-weights-after-edge-removals/description/
DFS框架,对于每个节点(x, parent=p)分别需要求解:
- a: 如果必须删除p->x这条边,也就是说x下面可能有最多k条边的最大权重
- b: 如果可以保留p->x这条边,也就是说x下面本身就有小于k条边的最大权重
我们可以得到每个节点(a, b+w)的pair. 其中w表示(x->y)的权重。b+w表示如果可以保留的话,那么可以获得的权重。
假设我们最先假设所有的边都需要cut掉,然后再考了将每个边都加回来。每条边加回来获得的增量是(b+w-a), 所以按照这个做排序就好。
class Solution:
def maximizeSumOfWeights(self, edges: List[List[int]], k: int) -> int:
n = len(edges) + 1
adj = [[] for _ in range(n)]
for u, v, w in edges:
adj[u].append((v, w))
adj[v].append((u, w))
def dfs(x, p) -> Tuple[int, int]:
# [a, b]
# a: 如果必须需要cut edge(p-x)才可以满足的最大值
# b: 如果不必须需要cut edge(p-x)就可以满足的最大值
if len(adj[x]) == 1 and adj[x][0] == p:
return 0, 0
child = []
for y, w in adj[x]:
if y == p: continue
a, b = dfs(y, x)
child.append((a, b + w))
# 不保留w, 可以得到a
# 保留边w, 可以得到b+w
child.sort(key=lambda x: x[1] - x[0], reverse=True)
base = sum([x[0] for x in child])
values = [base]
for a, bw in child:
base += (bw - a)
values.append(max(values[-1], base))
if len(values) >= (k + 1):
return values[k], values[k - 1]
else:
return values[-1], values[-1]
a, b = dfs(0, -1)
return max(a, b)