#3593
Medium Algorithms Minimum increments to equalize leaf paths
Array Dynamic Programming Tree Depth-First Search
41.2% acceptance
Feb 25, 2026
143
11
You are given n and an undirected tree rooted at node 0. Each node i has cost[i].
The score of a path is the sum of costs of all nodes along the path.
Make all root-to-leaf path scores equal by increasing node costs.
Return the minimum number of nodes whose cost must be increased.
Solution
Rust
Time O(n * m)
Space O(n * m)
impl Solution {
pub fn min_increase(n: i32, edges: Vec<Vec<i32>>, cost: Vec<i32>) -> i32 {
let n = n as usize;
let mut children = vec![vec![]; n];
for e in &edges {
let (u, v) = (e[0] as usize, e[1] as usize);
children[u].push(v);
children[v].push(u);
}
// Root the tree at 0 (orient edges away from root)
let mut parent = vec![usize::MAX; n];
let mut order = vec![];
let mut stack = vec![0usize];
let mut visited = vec![false; n];
visited[0] = true;
while let Some(u) = stack.pop() {
order.push(u);
for &v in &children[u] {
if !visited[v] {
visited[v] = true;
parent[v] = u;
stack.push(v);
}
}
}
// Post-order: process leaves first
// For each internal node, all children's subtree max scores must match.
// When they don't, we must increase some node's cost.
// To minimize number of changes: at each internal node, take the max of children's max path sums.
// Nodes that need to be increased are the ones where their subtree max < max.
// But each increase costs 1 count (we can always add to one node to equalize).
// Strategy: bottom-up, for each node compute max path sum below it.
// At each internal node with children: the max score among children's subtrees is the target.
// Children with lower scores need to be increased. For each such child, 1 node (the child itself
// or a deeper node). Minimum = number of children whose score < max.
// Wait: increasing one node can raise an entire subtree's paths.
// So: for each internal node, among its children's subtree max sums:
// Count how many are less than the maximum. Those must each have one node increased. Add that count.
let mut max_sum = vec![0i64; n];
for &u in order.iter().rev() {
max_sum[u] = cost[u] as i64;
let child_list: Vec<usize> = children[u].iter()
.filter(|&&v| parent[v] == u)
.cloned()
.collect();
if child_list.is_empty() {
// leaf: sum = cost[u]
} else {
let child_max = child_list.iter().map(|&c| max_sum[c]).max().unwrap();
max_sum[u] += child_max;
}
}
let mut ans = 0i32;
for &u in &order {
let child_list: Vec<usize> = children[u].iter()
.filter(|&&v| parent[v] == u)
.cloned()
.collect();
if child_list.len() < 2 { continue; }
let child_max = child_list.iter().map(|&c| max_sum[c]).max().unwrap();
for &c in &child_list {
if max_sum[c] < child_max {
ans += 1;
}
}
}
ans
}
}