# Delete Edge to minimize subtree sum difference

Given an undirected tree whose each **node is associated with a weight**. We need to delete an edge in such a way that difference between sum of weight in one subtree to sum of weight in other subtree is minimized.

**Example:**

In above tree, We have 6 choices for edge deletion, edge 0-1, subtree sum difference = 21 - 2 = 19 edge 0-2, subtree sum difference = 14 - 9 = 5 edge 0-3, subtree sum difference = 15 - 8 = 7 edge 2-4, subtree sum difference = 20 - 3 = 17 edge 2-5, subtree sum difference = 18 - 5 = 13 edge 3-6, subtree sum difference = 21 - 2 = 19

We can solve this problem using DFS. One **simple solution** is to delete each edge one by one and check subtree sum difference. Finally choose the minimum of them. This approach takes quadratic amount of time. An **efficient method **can solve this problem in linear time by calculating the sum of both subtrees using total sum of the tree. We can get the sum of other tree by subtracting sum of one subtree from the total sum of tree, in this way subtree sum difference can be calculated at each node in O(1) time. First we calculate the weight of complete tree and then while doing the DFS at each node, we calculate its subtree sum, by using these two values we can calculate subtree sum difference.

In below code, another array subtree is used to store sum of subtree rooted at node i in subtree[i]. DFS is called with current node index and parent index each time to loop over children only at each node.

Please see below code for better understanding.

## C++

`// C++ program to minimize subtree sum ` `// difference by one edge deletion ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `/* DFS method to traverse through edges, ` ` ` `calculating subtree sum at each node and ` ` ` `updating the difference between subtrees */` `void` `dfs(` `int` `u, ` `int` `parent, ` `int` `totalSum, ` ` ` `vector<` `int` `> edge[], ` `int` `subtree[], ` `int` `& res) ` `{ ` ` ` `int` `sum = subtree[u]; ` ` ` ` ` `/* loop for all neighbors except parent and ` ` ` `aggregate sum over all subtrees */` ` ` `for` `(` `int` `i = 0; i < edge[u].size(); i++) ` ` ` `{ ` ` ` `int` `v = edge[u][i]; ` ` ` `if` `(v != parent) ` ` ` `{ ` ` ` `dfs(v, u, totalSum, edge, subtree, res); ` ` ` `sum += subtree[v]; ` ` ` `} ` ` ` `} ` ` ` ` ` `// store sum in current node's subtree index ` ` ` `subtree[u] = sum; ` ` ` ` ` `/* at one side subtree sum is 'sum' and other side ` ` ` `subtree sum is 'totalSum - sum' so their difference ` ` ` `will be totalSum - 2*sum, by which we'll update ` ` ` `res */` ` ` `if` `(u != 0 && ` `abs` `(totalSum - 2*sum) < res) ` ` ` `res = ` `abs` `(totalSum - 2*sum); ` `} ` ` ` `// Method returns minimum subtree sum difference ` `int` `getMinSubtreeSumDifference(` `int` `vertex[], ` ` ` `int` `edges[][2], ` `int` `N) ` `{ ` ` ` `int` `totalSum = 0; ` ` ` `int` `subtree[N]; ` ` ` ` ` `// Calculating total sum of tree and initializing ` ` ` `// subtree sum's by vertex values ` ` ` `for` `(` `int` `i = 0; i < N; i++) ` ` ` `{ ` ` ` `subtree[i] = vertex[i]; ` ` ` `totalSum += vertex[i]; ` ` ` `} ` ` ` ` ` `// filling edge data structure ` ` ` `vector<` `int` `> edge[N]; ` ` ` `for` `(` `int` `i = 0; i < N - 1; i++) ` ` ` `{ ` ` ` `edge[edges[i][0]].push_back(edges[i][1]); ` ` ` `edge[edges[i][1]].push_back(edges[i][0]); ` ` ` `} ` ` ` ` ` `int` `res = INT_MAX; ` ` ` ` ` `// calling DFS method at node 0, with parent as -1 ` ` ` `dfs(0, -1, totalSum, edge, subtree, res); ` ` ` `return` `res; ` `} ` ` ` `// Driver code to test above methods ` `int` `main() ` `{ ` ` ` `int` `vertex[] = {4, 2, 1, 6, 3, 5, 2}; ` ` ` `int` `edges[][2] = {{0, 1}, {0, 2}, {0, 3}, ` ` ` `{2, 4}, {2, 5}, {3, 6}}; ` ` ` `int` `N = ` `sizeof` `(vertex) / ` `sizeof` `(vertex[0]); ` ` ` ` ` `cout << getMinSubtreeSumDifference(vertex, edges, N); ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Python3

`# Python3 program to minimize subtree ` `# Sum difference by one edge deletion ` ` ` `# DFS method to traverse through edges, ` `# calculating subtree Sum at each node and ` `# updating the difference between subtrees ` `def` `dfs(u, parent, totalSum, edge, ` ` ` `subtree, res): ` ` ` `Sum` `=` `subtree[u] ` ` ` ` ` `# loop for all neighbors except parent ` ` ` `# and aggregate Sum over all subtrees ` ` ` `for` `i ` `in` `range` `(` `len` `(edge[u])): ` ` ` `v ` `=` `edge[u][i] ` ` ` `if` `(v !` `=` `parent): ` ` ` `dfs(v, u, totalSum, edge, ` ` ` `subtree, res) ` ` ` `Sum` `+` `=` `subtree[v] ` ` ` ` ` `# store Sum in current node's ` ` ` `# subtree index ` ` ` `subtree[u] ` `=` `Sum` ` ` ` ` `# at one side subtree Sum is 'Sum' and ` ` ` `# other side subtree Sum is 'totalSum - Sum' ` ` ` `# so their difference will be totalSum - 2*Sum, ` ` ` `# by which we'll update res ` ` ` `if` `(u !` `=` `0` `and` `abs` `(totalSum ` `-` `2` `*` `Sum` `) < res[` `0` `]): ` ` ` `res[` `0` `] ` `=` `abs` `(totalSum ` `-` `2` `*` `Sum` `) ` ` ` `# Method returns minimum subtree ` `# Sum difference ` `def` `getMinSubtreeSumDifference(vertex, edges, N): ` ` ` `totalSum ` `=` `0` ` ` `subtree ` `=` `[` `None` `] ` `*` `N ` ` ` ` ` `# Calculating total Sum of tree ` ` ` `# and initializing subtree Sum's ` ` ` `# by vertex values ` ` ` `for` `i ` `in` `range` `(N): ` ` ` `subtree[i] ` `=` `vertex[i] ` ` ` `totalSum ` `+` `=` `vertex[i] ` ` ` ` ` `# filling edge data structure ` ` ` `edge ` `=` `[[] ` `for` `i ` `in` `range` `(N)] ` ` ` `for` `i ` `in` `range` `(N ` `-` `1` `): ` ` ` `edge[edges[i][` `0` `]].append(edges[i][` `1` `]) ` ` ` `edge[edges[i][` `1` `]].append(edges[i][` `0` `]) ` ` ` ` ` `res ` `=` `[` `999999999999` `] ` ` ` ` ` `# calling DFS method at node 0, ` ` ` `# with parent as -1 ` ` ` `dfs(` `0` `, ` `-` `1` `, totalSum, edge, subtree, res) ` ` ` `return` `res[` `0` `] ` ` ` `# Driver Code ` `if` `__name__ ` `=` `=` `'__main__'` `: ` ` ` ` ` `vertex ` `=` `[` `4` `, ` `2` `, ` `1` `, ` `6` `, ` `3` `, ` `5` `, ` `2` `] ` ` ` `edges ` `=` `[[` `0` `, ` `1` `], [` `0` `, ` `2` `], [` `0` `, ` `3` `], ` ` ` `[` `2` `, ` `4` `], [` `2` `, ` `5` `], [` `3` `, ` `6` `]] ` ` ` `N ` `=` `len` `(vertex) ` ` ` ` ` `print` `(getMinSubtreeSumDifference(vertex, ` ` ` `edges, N)) ` ` ` `# This code is contributed by PranchalK ` |

*chevron_right*

*filter_none*

**Output:**

5

This article is contributed by **Utkarsh Trivedi**. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.

## Recommended Posts:

- Subtree of all nodes in a tree using DFS
- Queries for M-th node in the DFS of subtree
- Even size subtree in n-ary tree
- Queries for DFS of a subtree in a tree
- Find the Kth node in the DFS traversal of a given subtree in a Tree
- Count of nodes having odd divisors in the given subtree for Q queries
- Find GCD of each subtree of a given node in an N-ary Tree for Q queries
- Queries for the number of nodes having values less than V in the subtree of a Node
- Edge Coloring of a Graph
- Count of distinct colors in a subtree of a Colored Tree with given min frequency for Q queries
- Program to Calculate the Edge Cover of a Graph
- Check if removing a given edge disconnects a graph
- Minimum edge reversals to make a root
- Paths to travel each nodes using each edge (Seven Bridges of Königsberg)
- Find weight of MST in a complete graph with edge-weights either 0 or 1
- Product of minimum edge weight between all pairs of a Tree
- Remove all outgoing edges except edge with minimum weight
- Maximize number of nodes which are not part of any edge in a Graph
- Tree, Back, Edge and Cross Edges in DFS of Graph
- Shortest Path in a weighted Graph where weight of an edge is 1 or 2