Program to find out the minimum value from sum of node values of sub-trees in Python

Suppose we have a tree with nodes numbered 1 to n, where each node contains an integer value. When we remove any edge from the tree, it splits into two sub-trees. Our goal is to find the minimum possible difference between the sums of node values in these two sub-trees.

The tree is given as a collection of edges, and the node values are provided in a list.

Problem Understanding

If the input is n = 6, edge_list = [[1, 2], [1, 3], [2, 4], [3, 5], [3, 6]], values = [15, 25, 15, 55, 15, 65], then the output will be 0.

1(15) 2(25) 3(15) 4(55) 5(15) 6(65)

Let's analyze what happens when we remove different edges ?

  • If edge (1,2) is removed: sum becomes 80 and 110, difference is 30
  • If edge (1,3) is removed: sum becomes 95 and 95, difference is 0
  • If edge (2,4) is removed: sum becomes 55 and 135, difference is 80
  • If edge (3,5) is removed: sum becomes 15 and 175, difference is 160
  • If edge (3,6) is removed: sum becomes 65 and 125, difference is 60

The minimum difference is 0.

Algorithm Approach

We use a bottom-up approach to calculate subtree sums:

  1. Build an adjacency list representation of the tree
  2. Start from leaf nodes and work towards the root
  3. For each node, calculate the sum of its subtree
  4. For each possible edge removal, calculate the difference between the two resulting subtrees
  5. Return the minimum difference found

Example

def solve(n, edge_list, values):
    # Build adjacency list
    adj_list = [[] for i in range(n)]
    
    for edge in edge_list:
        u = edge[0]
        v = edge[1]
        adj_list[u-1].append(v-1)
        adj_list[v-1].append(u-1)
    
    # Calculate subtree sums using bottom-up approach
    value_list = [0] * n
    not_visited = {i for i in range(n) if len(adj_list[i]) == 1}
    
    while len(not_visited):
        for i in not_visited:
            value_list[i] += values[i]
            if len(adj_list[i]):
                adj_list[adj_list[i][0]].remove(i)
                value_list[adj_list[i][0]] += value_list[i]
        
        not_visited = {adj_list[i][0] for i in not_visited if
                      len(adj_list[i]) and len(adj_list[adj_list[i][0]]) == 1}
    
    # Find minimum difference
    total_sum = sum(values)
    min_diff = abs(total_sum - 2 * value_list[0])
    
    for i in range(1, n):
        diff = abs(total_sum - 2 * value_list[i])
        if diff < min_diff:
            min_diff = diff
    
    return min_diff

# Test with the example
result = solve(6, [[1, 2], [1, 3], [2, 4], [3, 5], [3, 6]], [15, 25, 15, 55, 15, 65])
print("Minimum difference:", result)
Minimum difference: 0

How It Works

The algorithm works by:

  • Bottom-up processing: Starting from leaf nodes, we calculate subtree sums
  • Edge removal simulation: For each subtree sum, we calculate what would happen if we cut that subtree from the main tree
  • Difference calculation: If a subtree has sum S and total sum is T, then removing it creates subtrees with sums S and (T-S), so difference is |T - 2S|

Time Complexity

The time complexity is O(n) where n is the number of nodes, as we process each node exactly once. The space complexity is also O(n) for storing the adjacency list and auxiliary arrays.

Conclusion

This algorithm efficiently finds the minimum difference between subtree sums by using a bottom-up approach to calculate subtree weights. The key insight is that removing any edge creates two subtrees whose sum difference can be calculated using the total sum and one subtree's sum.

Updated on: 2026-03-26T18:12:01+05:30

230 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements