Open In App

Convert a tree to forest of even nodes

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a tree of n even nodes. The task is to find the maximum number of edges to be removed from the given tree to obtain a forest of trees having an even number of nodes. This problem is always solvable as the given graph has even nodes.

Examples: 

Input:

Convert-a-tree-to-forest-of-even-nodes-1


Output: 2
Explanation: By removing 2 edges shown below, we can obtain the forest with even node tree.

Convert-a-tree-to-forest-of-even-nodes-2

Approach:

The idea is to find a subtree with even number of nodes and remove it from rest of tree by removing the edge connecting it. After removal, we are left with tree with even node only because initially we have even number of nodes in the tree and removed subtree has also even node. Repeat the same procedure until we left with the tree that cannot be further decomposed in this manner.

To do this, the idea is to use Depth First Search to traverse the tree. Implement DFS function in such a manner that it will return number of nodes in the subtree whose root is node on which DFS is performed. If the number of nodes is even then remove the edge, else ignore.

C++
// C++ program to find maximum number to be removed
// to convert a tree into a forest containing trees of
// even number of nodes

#include<bits/stdc++.h>
using namespace std;

// Return the number of nodes of subtree having
// node as a root.
int dfs(vector<int> tree[], vector<int>& visit, int &ans, int node) {
    int num = 0, cnt = 0;

    // Mark node as visited.
    visit[node] = 1;

    // Traverse the adjacency list to find non-
    // visited node.
    for (int i = 0; i < tree[node].size(); i++) {
        if (visit[tree[node][i]] == 0) {
          
            // Finding number of nodes of the subtree
            // of a subtree.
            cnt = dfs(tree, visit, ans, tree[node][i]);

            // If nodes are even, increment number of
            // edges to be removed.
            if (cnt % 2 == 0) {
              	ans++;
            }
            else {
              
              	// Else leave the node as
              	// child of subtree.
              	num += cnt;
            }
        }
    }

    return num + 1;
}

// Return the maximum number of edges to remove
// to make the forest.
int maxEdge(vector<int> tree[], int n) {
    vector<int> visit(n + 2, 0);
    int ans = 0;

    dfs(tree, visit, ans, 1); 

    return ans;
}

int main() {
    int n = 10;

    vector<int> tree[n + 2];

    // Tree structure:
    //
    //            1
    //        /   |   \
    //      2     3    4
    //     / \     |    |
    //    5   6    7    8
    //                  / \
    //                9   10

    tree[1].push_back(2);
    tree[2].push_back(1);
    tree[1].push_back(3);
    tree[3].push_back(1);
    tree[1].push_back(4);
    tree[4].push_back(1);
    tree[2].push_back(5);
    tree[5].push_back(2);
    tree[2].push_back(6);
    tree[6].push_back(2);
    tree[3].push_back(7);
    tree[7].push_back(3);
    tree[4].push_back(8);
    tree[8].push_back(4);
    tree[8].push_back(9);
    tree[9].push_back(8);
    tree[8].push_back(10);
    tree[10].push_back(8);


    int result = maxEdge(tree, n);
    cout << result << endl;

    return 0;
}
Java
// Java program to find maximum number to be removed
// to convert a tree into a forest containing trees of
// even number of nodes

import java.util.ArrayList;
import java.util.Arrays;

class GfG {

    // Return the number of nodes of subtree having node as a root.
    static int dfs(ArrayList<Integer>[] tree, boolean[] visit,
                   int[] ans, int node) {
        int num = 0, cnt;

        // Mark node as visited.
        visit[node] = true;

        // Traverse the adjacency list to find non-visited node.
        for (int neighbor : tree[node]) {
            if (!visit[neighbor]) {

                // Finding number of nodes of the subtree
              	// of a subtree.
                cnt = dfs(tree, visit, ans, neighbor);

                // If nodes are even, increment number of edges to remove.
                if (cnt % 2 == 0) {
                    ans[0]++;
                } else {
                  
                    // Else leave the node as child of subtree.
                    num += cnt;
                }
            }
        }

        return num + 1;
    }

    // Return the maximum number of edges to remove
    // to make forest.
    static int maxEdge(ArrayList<Integer>[] tree, int n) {
        boolean[] visit = new boolean[n + 1];
        int[] ans = {0};
        Arrays.fill(visit, false);

        // Perform DFS from node 1
        dfs(tree, visit, ans, 1);

        return ans[0];
    }

    public static void main(String[] args) {
		
        int n = 10;
      
      	// Tree structure:
        //
        //            1
        //        /   |   \
        //      2     3    4
        //     / \     |   |
        //    5   6    7   8
        //                / \
        //               9   10

        ArrayList<Integer>[] tree = new ArrayList[n + 1];
        for (int i = 0; i < n + 1; i++) {
            tree[i] = new ArrayList<>();
        }

        tree[1].add(2);
        tree[2].add(1);
        tree[1].add(3);
        tree[3].add(1);
        tree[1].add(4);
        tree[4].add(1);
        tree[2].add(5);
        tree[5].add(2);
        tree[2].add(6);
        tree[6].add(2);
        tree[3].add(7);
        tree[7].add(3);
        tree[4].add(8);
        tree[8].add(4);
        tree[8].add(9);
        tree[9].add(8);
        tree[8].add(10);
        tree[10].add(8);

        System.out.println(maxEdge(tree, n));
    }
}
Python
# Python program to find maximum number to be removed
# to convert a tree into a forest containing trees of
# even number of nodes

def dfs(tree, visit, ans, node):
    num = 0

    # Mark node as visited.
    visit[node] = True

    # Traverse the adjacency list to find
    # non-visited node.
    for neighbor in tree[node]:
        if not visit[neighbor]:

            # Finding number of nodes of the subtree.
            cnt = dfs(tree, visit, ans, neighbor)

            # If nodes are even, increment number of
            # edges to remove.
            if cnt % 2 == 0:
                ans[0] += 1
            else:
                # Else leave the node as child of subtree.
                num += cnt

    return num + 1

# Return the maximum number of edge to remove
# to make forest.
def maxEdge(tree, n):
    visit = [False] * (n + 1)
    ans = [0]

    # Perform DFS from node 1
    dfs(tree, visit, ans, 1)

    return ans[0]

if __name__ == '__main__':
    
    n = 10
    # Tree structure:
    #
    #            1
    #        /   |   \
    #      2     3    4
    #     / \     |   |
    #    5   6    7    8
    #                  / \
    #                9   10
 
    tree = [[] for _ in range(n + 1)]

    tree[1].append(2)
    tree[2].append(1)
    tree[1].append(3)
    tree[3].append(1)
    tree[1].append(4)
    tree[4].append(1)
    tree[2].append(5)
    tree[5].append(2)
    tree[2].append(6)
    tree[6].append(2)
    tree[3].append(7)
    tree[7].append(3)
    tree[4].append(8)
    tree[8].append(4)
    tree[8].append(9)
    tree[9].append(8)
    tree[8].append(10)
    tree[10].append(8)
    print(maxEdge(tree, n))
C#
// C# program to find maximum number to be removed
// to convert a tree into a forest containing trees of
// even number of nodes

using System;
using System.Collections.Generic;

class GfG {

    // Return the number of nodes of subtree having node as a root.
    static int dfs(List<int>[] tree, bool[] visit,
                   ref int ans, int node) {
        int num = 0, cnt;

        // Mark node as visited.
        visit[node] = true;

        // Traverse the adjacency list to find non-visited node.
        foreach (int neighbor in tree[node]) {
            if (!visit[neighbor]) {

                // Finding number of nodes of the subtree.
                cnt = dfs(tree, visit, ref ans, neighbor);

                // If nodes are even, increment number
              	// of edges to remove.
                if (cnt % 2 == 0) {
                    ans++;
                } else {
                  
                    // Else leave the node as child of subtree.
                    num += cnt;
                }
            }
        }

        return num + 1;
    }

    // Return the maximum number of edges to remove
    // to make forest.
    static int maxEdge(List<int>[] tree, int n) {
        bool[] visit = new bool[n + 1];
        int ans = 0;

        // Perform DFS from node 1
        dfs(tree, visit, ref ans, 1);

        return ans;
    }

    static void Main(string[] args) {
     
        int n = 10;
      
      	// Tree structure:
        //
        //            1
        //        /   |   \
        //      2     3    4
        //     / \     |    |
        //    5   6    7    8
        //                  / \
        //                9   10

        List<int>[] tree = new List<int>[n + 1];
        for (int i = 0; i < n + 1; i++) {
            tree[i] = new List<int>();
        }

        tree[1].Add(2);
        tree[2].Add(1);
        tree[1].Add(3);
        tree[3].Add(1);
        tree[1].Add(4);
        tree[4].Add(1);
        tree[2].Add(5);
        tree[5].Add(2);
        tree[2].Add(6);
        tree[6].Add(2);
        tree[3].Add(7);
        tree[7].Add(3);
        tree[4].Add(8);
        tree[8].Add(4);
        tree[8].Add(9);
        tree[9].Add(8);
        tree[8].Add(10);
        tree[10].Add(8);
      
        Console.WriteLine(maxEdge(tree, n));
    }
}
JavaScript
// JavaScript program to find maximum number to be removed
// to convert a tree into a forest containing trees of
// even number of nodes

function dfs(tree, visit, ans, node) {
    let num = 0;

    // Mark node as visited.
    visit[node] = true;

    // Traverse the adjacency list to find non-visited node.
    for (let neighbor of tree[node]) {
        if (!visit[neighbor]) {

            // Finding number of nodes of the subtree.
            let cnt = dfs(tree, visit, ans, neighbor);

            // If nodes are even, increment number
            // of edges to remove.
            if (cnt % 2 === 0) {
                ans.count++;
            } else {
            
                // Else leave the node as child of subtree.
                num += cnt;
            }
        }
    }

    return num + 1;
}

// Return the maximum number of edges to remove
// to make forest.
function maxEdge(tree, n) {
    const visit = new Array(n + 1).fill(false);
    const ans = { count: 0 };

    // Perform DFS from node 1
    dfs(tree, visit, ans, 1);

    return ans.count;
}


const n = 10;

// Tree structure:
//
//            1
//        /   |   \
//      2     3    4
//     / \     |    |
//    5   6    7    8
//                  / \
//                9   10
const tree = Array.from({ length: n + 1 }, () => []);

tree[1].push(2);
tree[2].push(1);
tree[1].push(3);
tree[3].push(1);
tree[1].push(4);
tree[4].push(1);
tree[2].push(5);
tree[5].push(2);
tree[2].push(6);
tree[6].push(2);
tree[3].push(7);
tree[7].push(3);
tree[4].push(8);
tree[8].push(4);
tree[8].push(9);
tree[9].push(8);
tree[8].push(10);
tree[10].push(8);

console.log(maxEdge(tree, n));

Output
2

Time Complexity: O(n), where n is the number of nodes in tree.
Auxiliary Space: O(n) For taking visiting array.


Article Tags :
Practice Tags :

Similar Reads