class Solution {
public:
int componentValue(vector<int>& nums, vector<vector<int>>& edges) {
}
};
6211. 创建价值相同的连通块
有一棵 n
个节点的无向树,节点编号为 0
到 n - 1
。
给你一个长度为 n
下标从 0 开始的整数数组 nums
,其中 nums[i]
表示第 i
个节点的值。同时给你一个长度为 n - 1
的二维整数数组 edges
,其中 edges[i] = [ai, bi]
表示节点 ai
与 bi
之间有一条边。
你可以 删除 一些边,将这棵树分成几个连通块。一个连通块的 价值 定义为这个连通块中 所有 节点 i
对应的 nums[i]
之和。
你需要删除一些边,删除后得到的各个连通块的价值都相等。请返回你可以删除的边数 最多 为多少。
示例 1:
输入:nums = [6,2,2,2,6], edges = [[0,1],[1,2],[1,3],[3,4]] 输出:2 解释:上图展示了我们可以删除边 [0,1] 和 [3,4] 。得到的连通块为 [0] ,[1,2,3] 和 [4] 。每个连通块的价值都为 6 。可以证明没有别的更好的删除方案存在了,所以答案为 2 。
示例 2:
输入:nums = [2], edges = [] 输出:0 解释:没有任何边可以删除。
提示:
1 <= n <= 2 * 104
nums.length == n
1 <= nums[i] <= 50
edges.length == n - 1
edges[i].length == 2
0 <= edges[i][0], edges[i][1] <= n - 1
edges
表示一棵合法的树。原站题解
golang 解法, 执行用时: 200 ms, 内存消耗: 13.8 MB, 提交时间: 2023-08-28 10:30:03
func componentValue(nums []int, edges [][]int) int { g := make([][]int, len(nums)) for _, e := range edges { x, y := e[0], e[1] g[x] = append(g[x], y) g[y] = append(g[y], x) } var target int var dfs func(int, int) int dfs = func(x, fa int) int { sum := nums[x] // 价值 for _, y := range g[x] { if y != fa { res := dfs(y, x) if res < 0 { return -1 } sum += res } } if sum > target { return -1 } if sum == target { return 0 } return sum } total, mx := 0, 0 for _, x := range nums { total += x mx = max(mx, x) } for i := total / mx; ; i-- { if total%i == 0 { target = total / i if dfs(0, -1) == 0 { return i - 1 } } } } func min(a, b int) int { if b < a { return b }; return a } func max(a, b int) int { if b > a { return b }; return a }
cpp 解法, 执行用时: 380 ms, 内存消耗: 129.5 MB, 提交时间: 2023-08-28 10:29:48
class Solution { public: int componentValue(vector<int> &nums, vector<vector<int>> &edges) { vector<vector<int>> g(nums.size()); for (auto &e : edges) { int x = e[0], y = e[1]; g[x].push_back(y); g[y].push_back(x); } int target; function<int(int, int)> dfs = [&](int x, int fa) { int sum = nums[x]; // 价值 for (int y : g[x]) if (y != fa) { int res = dfs(y, x); if (res < 0) return -1; sum += res; } if (sum > target) return -1; return sum < target ? sum : 0; }; int total = accumulate(nums.begin(), nums.end(), 0); int mx = *max_element(nums.begin(), nums.end()); for (int i = total / mx;; --i) if (total % i == 0) { target = total / i; if (dfs(0, -1) == 0) return i - 1; } } };
java 解法, 执行用时: 64 ms, 内存消耗: 57 MB, 提交时间: 2023-08-28 10:29:35
class Solution { private List<Integer>[] g; private int[] nums; private int target; public int componentValue(int[] nums, int[][] edges) { g = new ArrayList[nums.length]; Arrays.setAll(g, e -> new ArrayList<>()); for (var e : edges) { int x = e[0], y = e[1]; g[x].add(y); g[y].add(x); } this.nums = nums; var total = Arrays.stream(nums).sum(); var max = Arrays.stream(nums).max().orElseThrow(); for (var i = total / max; ; --i) if (total % i == 0) { target = total / i; if (dfs(0, -1) == 0) return i - 1; } } private int dfs(int x, int fa) { var sum = nums[x]; // 价值 for (var y : g[x]) if (y != fa) { var res = dfs(y, x); if (res < 0) return -1; sum += res; } if (sum > target) return -1; return sum < target ? sum : 0; } }
python3 解法, 执行用时: 340 ms, 内存消耗: 47.6 MB, 提交时间: 2023-08-28 10:29:21
class Solution: def componentValue(self, nums: List[int], edges: List[List[int]]) -> int: g = [[] for _ in nums] for x, y in edges: g[x].append(y) g[y].append(x) def dfs(x: int, fa: int) -> int: s = nums[x] # 价值 for y in g[x]: if y != fa: res = dfs(y, x) if res < 0: return -1 s += res if s > target: return -1 return s if s < target else 0 total = sum(nums) for i in range(total // max(nums), 1, -1): if total % i == 0: target = total // i if dfs(0, -1) == 0: return i - 1 return 0