Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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.
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:
- Build an adjacency list representation of the tree
- Start from leaf nodes and work towards the root
- For each node, calculate the sum of its subtree
- For each possible edge removal, calculate the difference between the two resulting subtrees
- 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.
