Skip to main content
Back to problems
#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)
LeetCode
solution.rs
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
  }
}