每日一题 2646. 最小化旅行的价格总和(困难,树)

每日一题 2646. 最小化旅行的价格总和(困难,树)_第1张图片

  1. 分解为两个子问题,树中节点到节点的路径问题,价格减半树的最小值问题
  2. 由于它是无向的树,所以对于每一次旅行,以 start 为根,通过dfs寻找 end 就可以很简单地找到需要的路径且它是唯一的,这里我们统计每经过一个节点就令它的价格多加一份
  3. 通过第二步,我们得到了一棵全新的价格树,然后只要通过树形动态规划的方法,求得最小值即可
class Solution:
    def minimumTotalPrice(self, n: int, edges: List[List[int]], price: List[int], trips: List[List[int]]) -> int:
        ed = defaultdict(list)
        for edge in edges:
            ed[edge[0]].append(edge[1])
            ed[edge[1]].append(edge[0])

        pt = [0] * n

        def dfs(node, fa, to):
            if node == to:
                pt[node] += price[node]
                return True

            for ch in ed[node]:
                if ch == fa:
                    continue
                if dfs(ch, node, to):
                    pt[node] += price[node]
                    return True

            return False
        
        for trip in trips:
            dfs(trip[0], -1, trip[1])

        def cut(node, fa):
            docut = pt[node] // 2
            nocut = pt[node]
            for ch in ed[node]:
                if ch == fa:
                    continue
                a,b = cut(ch, node)
                docut += b
                nocut += min(a, b)
            return docut, nocut

        return min(cut(trips[0][0], -1))

你可能感兴趣的:(用Python刷力扣,python,算法,leetcode)