LC 6211. 创建价值相同的连通块

https://leetcode.cn/contest/biweekly-contest-89/problems/create-components-with-same-value/

这题迟迟不敢下手,也是不知道里面有什么玄机。看了第一名的题解,大致确定思路就是枚举所有可能的价值,然后验证这个价值是否可以满足。

我之前没有太写过这种在树上的DFS算法,看了第一名题解,觉得相比图的遍历可以简化不少:不用维护visited, 只需要记录parent就行,访问的时候避开parent.

然后这个验证过程也很有技巧:

看了他写的代码之后觉得非常简单,但是遍历和子树拆解纠缠在一起,就迟迟不敢下手。

class Solution:
    def componentValue(self, nums: List[int], edges: List[List[int]]) -> int:
        n = len(nums)
        adj = [[] for _ in range(n)]
        for x, y in edges:
            adj[x].append(y)
            adj[y].append(x)

        def dfs(x, parent, target):
            s = nums[x]

            for y in adj[x]:
                if y == parent: continue
                res = dfs(y, x, target)
                if res < 0:
                    return -1
                s += res

            if s > target:
                return -1
            if s == target:
                return 0
            return s

        M = max(nums)
        total = sum(nums)
        part = total // M
        for p in reversed(range(1, part + 1)):
            if total % p == 0:
                target = total // p
                assert target >= M
                if dfs(0, -1, target) == 0:
                    return p - 1