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* ar,         vector& 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* ar, int& val){     val++;     for (int child : ar[n]) {        if (child != par) {            dfs2(child, n, ar, val);        }    }} int minimumEdges(int n,                 vector >& edges){     vector ar[n];    vector size(n, 0);     // Create the graph    // From the given input.    for (int i = 0; i < n - 1; i++) {        ar[edges[i][0]]            .push_back(edges[i][1]);        ar[edges[i][1]]            .push_back(edges[i][0]);    }     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 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 codeint 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 Codeif __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 subtree_size = new List ();     // 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