 GeeksforGeeks App
Open App Browser
Continue

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

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`

## Javascript

 ``

Output

`2`

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

My Personal Notes arrow_drop_up