# Minimize deletion of edges to convert Tree into a forest of size at most N/2

• Difficulty Level : Hard
• Last Updated : 01 Jul, 2022

Given a tree with N nodes, numbered from 0 to N – 1, the task is to find the minimum number of deletion of edges, such that, the tree is converted into a forest where each tree in the forest can have size less than equal to ⌊N/2⌋.

Examples:

Input: N = 3, edges = [[0, 1], [0, 2]]
0
/      \
1            2
Output:  2
Explanation: The maximum size of each tree after removing the edges can be 1.
So every node has to be separated from each other.
So, remove all the 2 edges present in the tree.
Hence, the answer will be 2.

Input: N = 7, edges =  [[0, 1], [1, 2], [1, 3], [0, 4], [4, 5], [4, 6]]
0
/       \
1               4
/      \          /     \
2           3       5        6
Output: 2
Explanation: Remove the edges (0 – 1) and (0 – 4) to satisfy the condition. Hence, the answer will be 2.

Approach: The idea to solve the problem is using Depth First Search

Follow the steps to solve the given problem:

• Create the graph from the given input.
• Calculate the centroids using the dfs function.
• If the tree has two centroids, then the answer will be 1.
• Else, declare a vector subtreeSize, which will calculate the subtree size of all the children of the centroid.
• Calculate the subtree sizes using the dfs2 function.
• Declare two variables, ans and sum, to store the answer and the number of nodes removed due to the removal of edges.
• Sort the subtreeSize in descending order.
• Iterate over the subtreeSize vector.
• Add the current value to the sum and increase the ans by 1.
• If the remaining nodes are less than or equal to N/ 2
• Break the loop.
• Finally, return the ans.

Below is the implementation of the above approach :

## C++

 `// C++ Code for the above approach:` `#include ` `using` `namespace` `std;`   `// Function to calculate the` `// Centroids of the tree.` `void` `dfs(``int` `n, ``int` `par,` `         ``vector<``int``>* ar,` `         ``vector<``int``>& size,` `         ``int``& cent1, ``int``& cent2,` `         ``int``& some, ``int` `tot)` `{`   `    ``size[n] = 1;` `    ``int` `mx = 0;`   `    ``// Iterate through the children` `    ``// of the current node and` `    ``// store the maximum of the subtree size` `    ``// among the children in the mx variable.` `    ``for` `(``int` `child : ar[n]) {`   `        ``if` `(child != par) {`   `            ``dfs(child, n, ar, size,` `                ``cent1, cent2, some, tot);` `            ``size[n] += size[child];` `            ``mx = max(mx, size[child]);` `        ``}` `    ``}`   `    ``mx = max(mx, tot - size[n]);`   `    ``// If mx is smaller than the maximum` `    ``// subtree size till now,` `    ``// update that and centroids accordingly.` `    ``if` `(mx < some) {` `        ``some = mx;` `        ``cent1 = n;` `        ``cent2 = -1;` `    ``}` `    ``else` `if` `(mx == some) {` `        ``cent2 = n;` `    ``}` `}`   `// Function to calculate the subtree` `// size of the given node.` `void` `dfs2(``int` `n, ``int` `par,` `          ``vector<``int``>* ar, ``int``& val)` `{`   `    ``val++;`   `    ``for` `(``int` `child : ar[n]) {` `        ``if` `(child != par) {` `            ``dfs2(child, n, ar, val);` `        ``}` `    ``}` `}`   `int` `minimumEdges(``int` `n,` `                 ``vector >& edges)` `{`   `    ``vector<``int``> ar[n];` `    ``vector<``int``> size(n, 0);`   `    ``// Create the graph` `    ``// From the given input.` `    ``for` `(``int` `i = 0; i < n - 1; i++) {` `        ``ar[edges[i]]` `            ``.push_back(edges[i]);` `        ``ar[edges[i]]` `            ``.push_back(edges[i]);` `    ``}`   `    ``int` `cent1 = -1, cent2 = -1, some = 1000000;`   `    ``// Calculate the centroids` `    ``// Using the dfs function.` `    ``dfs(0, -1, ar, size,` `        ``cent1, cent2, some, n);`   `    ``// If the tree has two centroids,` `    ``// Then the answer will be 1.` `    ``if` `(cent2 != -1) {` `        ``return` `1;` `    ``}`   `    ``// Declare a vector subtreeSize,` `    ``// Which will calculate the` `    ``// Subtree size of all the children` `    ``// Of the centroid.` `    ``vector<``int``> subtree_size;`   `    ``// Calculate the subtree sizes` `    ``// Using the dfs2 function.` `    ``for` `(``int` `x : ar[cent1]) {` `        ``int` `val = 0;` `        ``dfs2(x, cent1, ar, val);` `        ``subtree_size.push_back(val);` `    ``}`   `    ``// Declare two variables, ans and sum,` `    ``// To store the answer` `    ``// And the number of nodes removed` `    ``// Due to the removal of edges.` `    ``int` `sum = 0;` `    ``int` `ans = 0;`   `    ``// Sort the subtreeSize` `    ``// In descending order.` `    ``sort(subtree_size.rbegin(),` `         ``subtree_size.rend());`   `    ``// Iterate over the “subtreeSize” vector.` `    ``for` `(``int` `x : subtree_size) {`   `        ``// Add the current value to the sum` `        ``// And increase the ans by 1.` `        ``sum += x;` `        ``ans++;`   `        ``// If the remaining nodes are` `        ``// Less than or equal to N / 2,` `        ``// Break the loop.` `        ``if` `(n - sum <= n / 2) {` `            ``break``;` `        ``}` `    ``}`   `    ``// Finally, return the ans.` `    ``return` `ans;` `}`   `// Driver code` `int` `main()` `{` `    ``int` `N = 3;` `    ``vector > edges` `        ``= { { 0, 1 }, { 0, 2 } };` `    ``cout << minimumEdges(N, edges) << ``"\n"``;` `    ``return` `0;` `}`

## Java

 `// Java code for the above approach:`   `import` `java.util.*; `   `public` `class` `Main {`   `  ``static` `int` `cent1,cent2;` `  ``static` `int``[] size;` `  ``static` `int` `val;` `  ``// Function to calculate the` `  ``// Centroids of the tree.` `  ``static` `void` `dfs(``int` `n, ``int` `par,` `                  ``ArrayList > ar,` `                  ``int` `some, ``int` `tot)` `  ``{`   `    ``size[n] = ``1``;` `    ``int` `mx = ``0``;`   `    ``// Iterate through the children` `    ``// of the current node and` `    ``// store the maximum of the subtree size` `    ``// among the children in the mx variable.` `    ``for` `(``int` `child : ar.get(n)) {`   `      ``if` `(child != par) {`   `        ``dfs(child, n, ar, some, tot);` `        ``size[n] += size[child];` `        ``mx = Math.max(mx, size[child]);` `      ``}` `    ``}`   `    ``mx = Math.max(mx, tot - size[n]);`   `    ``// If mx is smaller than the maximum` `    ``// subtree size till now,` `    ``// update that and centroids accordingly.` `    ``if` `(mx < some) {` `      ``some = mx;` `      ``cent1 = n;` `      ``cent2 = -``1``;` `    ``}` `    ``else` `if` `(mx == some) {` `      ``cent2 = n;` `    ``}` `  ``}`     `  ``// Function to calculate the subtree` `  ``// size of the given node.` `  ``static` `void` `dfs2(``int` `n, ``int` `par,` `                   ``ArrayList > ar)` `  ``{`   `    ``val++;`   `    ``for` `(``int` `child : ar.get(n)) {` `      ``if` `(child != par) {` `        ``dfs2(child, n, ar);` `      ``}` `    ``}` `  ``}`   `  ``static` `int` `minimumEdges(``int` `n,``int``[][] edges)` `  ``{`   `    ``ArrayList > ar` `      ``= ``new` `ArrayList > (n);` `    ``for``(``int` `i=``0``; i () );` `    ``}` `    ``size = ``new` `int``[n]; ` `    ``Arrays.fill(size, ``0``);` `    ``// Create the graph` `    ``// From the given input.` `    ``for` `(``int` `i = ``0``; i < n - ``1``; i++) {` `      ``ar.get(edges[i][``0``])` `        ``.add(edges[i][``1``]);` `      ``ar.get(edges[i][``1``])` `        ``.add(edges[i][``0``]);` `    ``}`   `    ``cent1 = -``1``; ` `    ``cent2 = -``1``; ` `    ``int` `some = ``1000000``;`   `    ``// Calculate the centroids` `    ``// Using the dfs function.` `    ``dfs(``0``, -``1``, ar, some, n);`   `    ``// If the tree has two centroids,` `    ``// Then the answer will be 1.` `    ``if` `(cent2 != -``1``) {` `      ``return` `1``;` `    ``}`   `    ``// Declare a vector subtreeSize,` `    ``// Which will calculate the` `    ``// Subtree size of all the children` `    ``// Of the centroid.` `    ``ArrayList subtree_size = ``new` `ArrayList ();`   `    ``// Calculate the subtree sizes` `    ``// Using the dfs2 function.` `    ``for` `(``int` `x : ar.get(cent1) ) {` `      ``val = ``0``;` `      ``dfs2(x, cent1, ar);` `      ``subtree_size.add(val);` `    ``}`   `    ``// Declare two variables, ans and sum,` `    ``// To store the answer` `    ``// And the number of nodes removed` `    ``// Due to the removal of edges.` `    ``int` `sum = ``0``;` `    ``int` `ans = ``0``;`   `    ``// Sort the subtreeSize` `    ``// In descending order.` `    ``Collections.sort(subtree_size);`   `    ``// Iterate over the “subtreeSize” vector.` `    ``for` `(``int` `x : subtree_size) {`   `      ``// Add the current value to the sum` `      ``// And increase the ans by 1.` `      ``sum += x;` `      ``ans++;`   `      ``// If the remaining nodes are` `      ``// Less than or equal to N / 2,` `      ``// Break the loop.` `      ``if` `(n - sum <= n / ``2``) {` `        ``break``;` `      ``}` `    ``}`   `    ``// Finally, return the ans.` `    ``return` `ans;` `  ``}`   `  ``// Driver Code` `  ``public` `static` `void` `main(String args[])` `  ``{` `    ``int` `N = ``3``;` `    ``int``[][] edges` `      ``= { { ``0``, ``1` `}, { ``0``, ``2` `} };`   `    ``// Function call` `    ``System.out.println( minimumEdges(N, edges) );`   `  ``}` `}`   `// This code has been contributed by Sachin Sahara (sachin801)`

## Python3

 `## Function to calculate the ` `## Centroids of the tree. ` `def` `dfs(n, par, ar, size, lis, tot) :` `  `  `    ``size[n] ``=` `1` `    ``mx ``=` `0` `  `  `    ``## Iterate through the children ` `    ``## of the current node and ` `    ``## store the maximum of the subtree size ` `    ``## among the children in the mx variable. ` `    ``for` `child ``in` `ar[n]: ` `  `  `        ``if` `(child !``=` `par):` `            ``dfs(child, n, ar, size, lis, tot)` `            ``size[n] ``+``=` `size[child]` `            ``mx ``=` `max``(mx, size[child])` `  `  `    ``mx ``=` `max``(mx, tot ``-` `size[n]); ` `  `  `    ``## If mx is smaller than the maximum ` `    ``## subtree size till now, ` `    ``## update that and centroids accordingly. ` `    ``if` `(mx < lis[``2``]):` `        ``lis[``2``] ``=` `mx; ` `        ``lis[``0``] ``=` `n; ` `        ``lis[``1``] ``=` `-``1``;` `    ``elif` `(mx ``=``=` `lis[``2``]):` `        ``lis[``1``] ``=` `n;`   `## Function to calculate the subtree ` `## size of the given node. ` `def` `dfs2(n, par, ar, val):` `  `  `    ``val ``=` `1` `  `  `    ``for` `child ``in` `ar[n]: ` `        ``if` `(child !``=` `par):` `            ``val ``+``=` `dfs2(child, n, ar, val)`   `    ``return` `val`     `def` `minimumEdges(n, edges): ` `    ``ar ``=` `[]` `    ``size ``=` `[]` `    `  `    ``for` `i ``in` `range``(n):` `        ``ar.append(``list``())` `        ``size.append(``0``)` `    `  `    ``## Create the graph ` `    ``## From the given input. ` `    ``for` `i ``in` `range``(n``-``1``):` `        ``ar[edges[i][``0``]].append(edges[i][``1``])` `        ``ar[edges[i][``1``]].append(edges[i][``0``])`   `    ``cent1 ``=` `-``1` `    ``cent2 ``=` `-``1` `    ``some ``=` `1000000`   `    ``lis ``=` `[``-``1``, ``-``1``, ``1000000``]`   `    ``## Calculate the centroids ` `    ``## Using the dfs function. ` `    ``dfs(``0``, ``-``1``, ar, size, lis, n); ` `  `  `    ``cent1 ``=` `lis[``0``]` `    ``cent2 ``=` `lis[``1``]` `    ``some ``=` `lis[``2``]`   `    ``## If the tree has two centroids, ` `    ``## Then the answer will be 1. ` `    ``if` `(cent2 !``=` `-``1``):` `        ``return` `1` `  `  `    ``## Declare a vector subtreeSize, ` `    ``## Which will calculate the ` `    ``## Subtree size of all the children ` `    ``## Of the centroid. ` `    ``subtree_size ``=` `[]`   `    ``## Calculate the subtree sizes ` `    ``## Using the dfs2 function. ` `    ``for`  `x ``in` `ar[cent1]: ` `        ``val ``=` `0` `        ``val ``=` `dfs2(x, cent1, ar, val)` `        ``subtree_size.append(val)` `  `  `    ``## Declare two variables, ans and sum, ` `    ``## To store the answer ` `    ``## And the number of nodes removed ` `    ``## Due to the removal of edges. ` `    ``sum` `=` `0` `    ``ans ``=` `0` `  `  `    ``## Sort the subtreeSize ` `    ``## In descending order. ` `    ``subtree_size.sort()` `  `  `    ``## Iterate over the “subtreeSize” vector. ` `    ``for` `x ``in` `subtree_size: ` `  `  `        ``## Add the current value to the sum ` `        ``## And increase the ans by 1. ` `        ``sum` `+``=` `x` `        ``ans ``+``=` `1` `  `  `        ``## If the remaining nodes are ` `        ``## Less than or equal to N / 2, ` `        ``## Break the loop. ` `        ``if` `(n ``-` `sum` `<``=` `n ``/` `2``):` `            ``break``;`   `    ``return` `ans`   `# Driver Code` `if` `__name__ ``=``=` `"__main__"``:`   `    ``N ``=` `3` `    ``edges ``=` `list``((``list``((``0``, ``1``)), ``list``((``0``, ``2``))))`   `    ``print``(minimumEdges(N, edges))` `    `  `    ``# This code is contributed by subhamgoyal2014.`

## C#

 `// C# code for the above approach:` `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `GFG {`   `  ``static` `int` `cent1,cent2;` `  ``static` `int``[] size;` `  ``static` `int` `val;`   `  ``// Function to calculate the` `  ``// Centroids of the tree.` `  ``static` `void` `dfs(``int` `n, ``int` `par,` `                  ``List > ar,` `                  ``int` `some, ``int` `tot)` `  ``{`   `    ``size[n] = 1;` `    ``int` `mx = 0;`   `    ``// Iterate through the children` `    ``// of the current node and` `    ``// store the maximum of the subtree size` `    ``// among the children in the mx variable.` `    ``foreach` `(``int` `child ``in` `ar[n]) {`   `      ``if` `(child != par) {`   `        ``dfs(child, n, ar, some, tot);` `        ``size[n] += size[child];` `        ``mx = Math.Max(mx, size[child]);` `      ``}` `    ``}`   `    ``mx = Math.Max(mx, tot - size[n]);`   `    ``// If mx is smaller than the maximum` `    ``// subtree size till now,` `    ``// update that and centroids accordingly.` `    ``if` `(mx < some) {` `      ``some = mx;` `      ``cent1 = n;` `      ``cent2 = -1;` `    ``}` `    ``else` `if` `(mx == some) {` `      ``cent2 = n;` `    ``}` `  ``}`     `  ``// Function to calculate the subtree` `  ``// size of the given node.` `  ``static` `void` `dfs2(``int` `n, ``int` `par,` `                   ``List > ar)` `  ``{`   `    ``val++;`   `    ``foreach` `(``int` `child ``in` `ar[n]) {` `      ``if` `(child != par) {` `        ``dfs2(child, n, ar);` `      ``}` `    ``}` `  ``}`   `  ``static` `int` `minimumEdges(``int` `n,``int``[,] edges)` `  ``{`   `    ``List > ar` `      ``= ``new` `List > (n);` `    ``for``(``int` `i=0; i () );` `    ``}` `    ``size = ``new` `int``[n]; `   `    ``//  Arrays.fill(size, 0);` `    ``// Create the graph` `    ``// From the given input.` `    ``for` `(``int` `i = 0; i < n - 1; i++) {` `      ``ar[edges[i,0]]` `        ``.Add(edges[i,1]);` `      ``ar[edges[i,1]]` `        ``.Add(edges[i,0]);` `    ``}`   `    ``cent1 = -1; ` `    ``cent2 = -1; ` `    ``int` `some = 1000000;`   `    ``// Calculate the centroids` `    ``// Using the dfs function.` `    ``dfs(0, -1, ar, some, n);`   `    ``// If the tree has two centroids,` `    ``// Then the answer will be 1.` `    ``if` `(cent2 != -1) {` `      ``return` `1;` `    ``}`   `    ``// Declare a vector subtreeSize,` `    ``// Which will calculate the` `    ``// Subtree size of all the children` `    ``// Of the centroid.` `    ``List <``int``> subtree_size = ``new` `List <``int``> ();`   `    ``// Calculate the subtree sizes` `    ``// Using the dfs2 function.` `    ``foreach` `(``int` `x ``in` `ar[cent1] ) {` `      ``val = 0;` `      ``dfs2(x, cent1, ar);` `      ``subtree_size.Add(val);` `    ``}`   `    ``// Declare two variables, ans and sum,` `    ``// To store the answer` `    ``// And the number of nodes removed` `    ``// Due to the removal of edges.` `    ``int` `sum = 0;` `    ``int` `ans = 0;`   `    ``// Sort the subtreeSize` `    ``// In descending order.` `    ``subtree_size.Sort();`   `    ``// Iterate over the “subtreeSize�? vector.` `    ``foreach` `(``int` `x ``in` `subtree_size) {`   `      ``// Add the current value to the sum` `      ``// And increase the ans by 1.` `      ``sum += x;` `      ``ans++;`   `      ``// If the remaining nodes are` `      ``// Less than or equal to N / 2,` `      ``// Break the loop.` `      ``if` `(n - sum <= n / 2) {` `        ``break``;` `      ``}` `    ``}`   `    ``// Finally, return the ans.` `    ``return` `ans;` `  ``}`   `  ``// Driver Code` `  ``public` `static` `void` `Main(String []args)` `  ``{` `    ``int` `N = 3;` `    ``int``[,] edges` `      ``= { { 0, 1 }, { 0, 2 } };`   `    ``// Function call` `    ``Console.WriteLine( minimumEdges(N, edges) );` `  ``}` `}`   `// This code is contributed by shikhasingrajput `

Output

`2`

Time Complexity: O(N * log(N))
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Recommended Articles
Page :