Maximum edge removal from tree to make even forest - GeeksforGeeks

22 Jun, 2021
Given an undirected tree which has even number of vertices, we need to remove the maximum number of edges from this tree such that each connected component of the resultant forest has an even number of vertices. 
Examples: 
In above shown tree, we can remove at max 2 
edges 0-2 and 0-4 shown in red such that each
connected component will have even number of
vertices.
As we need connected components that have even number of vertices so when we get one component we can remove the edge that connects it to the remaining tree and we will be left with a tree with even number of vertices which will be the same problem but of smaller size, we have to repeat this algorithm until the remaining tree cannot be decomposed further in the above manner. 
We will traverse the tree using DFS which will return the number of vertices in the component of which the current node is the root. If a node gets an even number of vertices from one of its children then the edge from that node to its child will be removed and result will be increased by one and if the returned number is odd then we will add it to the number of vertices that the component will have if the current node is the root of it.
1) Do DFS from any starting node as tree
is connected.

2) Initialize count of nodes in subtree rooted
under current node as 0.

3) Do following recursively for every subtree
of current node.
    a) If size of current subtree is even,
       increment result by 1 as we can 
       disconnect the subtree.
    b) Else add count of nodes in current 
       subtree to current count.
Please see below code for better understanding, 
C++14
Java
Python3
C#
Javascript
/* Program to get maximum number of edges which   can be removed such that each connected component   of this tree will have an even number of vertices */#include <bits/stdc++.h>using namespace std; // Utility method to do DFS of the graph and count edge// deletion for even forestint dfs(vector<int> g[], int u, bool visit[], int& res){    visit[u] = true;    int currComponentNode = 0;     //  iterate over all neighbor of node u    for (int i = 0; i < g[u].size(); i++)    {        int v = g[u][i];        if (!visit[v])        {            // Count the number of nodes in a subtree            int subtreeNodeCount = dfs(g, v, visit, res);             // if returned node count is even, disconnect            // the subtree and increase result by one.            if (subtreeNodeCount % 2 == 0)                res++;             //  else add subtree nodes in current component            else                currComponentNode += subtreeNodeCount;        }    }     // number of nodes in current component and one for    // current node    return (currComponentNode + 1);} /*  method returns max edge that we can remove, after which    each  connected component will have even number of    vertices */int maxEdgeRemovalToMakeForestEven(vector<int> g[], int N){    // Create a visited array for DFS and make all nodes    // unvisited in starting    bool visit[N + 1];    for (int i = 0; i <= N; i++)        visit[i] = false;     int res = 0; // Passed as reference     //  calling the dfs from node-0    dfs(g, 0, visit, res);     return res;} // Utility function to add an undirected edge (u,v)void addEdge(vector<int> g[], int u, int v){    g[u].push_back(v);    g[v].push_back(u);} //  Driver code to test above methodsint main(){    int edges[][2] = {{0, 2}, {0, 1}, {0, 4},                      {2, 3}, {4, 5}, {5, 6},                      {5, 7}};    int N = sizeof(edges)/sizeof(edges[0]);    vector<int> g[N + 1];    for (int i = 0; i < N; i++)         addEdge(g, edges[i][0], edges[i][1]);     cout << maxEdgeRemovalToMakeForestEven(g, N);    return 0;}
/* Program to get maximum number of edges whichcan be removed such that each connected componentof this tree will have an even number of vertices */import java.util.*;class GFG{     // graphstatic Vector<Vector<Integer>> g = new Vector<Vector<Integer>>(); static int res; // Utility method to do DFS of the graph and count edge// deletion for even foreststatic int dfs( int u, boolean visit[]){    visit[u] = true;    int currComponentNode = 0;     // iterate over all neighbor of node u    for (int i = 0; i < g.get(u).size(); i++)    {        int v = g.get(u).get(i);        if (!visit[v])        {            // Count the number of nodes in a subtree            int subtreeNodeCount = dfs(v, visit);             // if returned node count is even, disconnect            // the subtree and increase result by one.            if (subtreeNodeCount % 2 == 0)                res++;             // else add subtree nodes in current component            else                currComponentNode += subtreeNodeCount;        }    }     // number of nodes in current component and one for    // current node    return (currComponentNode + 1);} /* method returns max edge that we can remove, after which    each connected component will have even number of    vertices */static int maxEdgeRemovalToMakeForestEven( int N){    // Create a visited array for DFS and make all nodes    // unvisited in starting    boolean visit[]=new boolean[N + 1];    for (int i = 0; i <= N; i++)        visit[i] = false;     res = 0; // Passed as reference     // calling the dfs from node-0    dfs(0, visit);     return res;} // Utility function to add an undirected edge (u,v)static void addEdge( int u, int v){    g.get(u).add(v);    g.get(v).add(u);} // Driver code to test above methodspublic static void main(String args[]){    int edges[][] = {{0, 2}, {0, 1}, {0, 4},                    {2, 3}, {4, 5}, {5, 6},                    {5, 7}};    int N = edges.length;         for (int i = 0; i < N+1; i++)    g.add(new Vector<Integer>());         for (int i = 0; i < N; i++)        addEdge( edges[i][0], edges[i][1]);              System.out.println(maxEdgeRemovalToMakeForestEven( N));}} // This code is contributed by Arnab Kundu
# Python3 program to get maximum number of# edges which can be removed such that each# connected component of this tree will# have an even number of verticesfrom typing import List # Utility method to do DFS of the graph# and count edge deletion for even forestdef dfs(u: int, visit: List[bool]) -> int:         global res, g     visit[u] = True    currComponentNode = 0     # Iterate over all neighbor of node u    for i in range(len(g[u])):        v = g[u][i]                 if (not visit[v]):             # Count the number of nodes in a subtree            subtreeNodeCount = dfs(v, visit)             # If returned node count is even, disconnect            # the subtree and increase result by one.            if (subtreeNodeCount % 2 == 0):                res += 1             # Else add subtree nodes in            # current component            else:                currComponentNode += subtreeNodeCount     # Number of nodes in current component    # and one for current node    return (currComponentNode + 1) # Method returns max edge that we can remove,# after which each connected component will# have even number of verticesdef maxEdgeRemovalToMakeForestEven(N: int) -> int:         # Create a visited array for DFS and make    # all nodes unvisited in starting    visit = [False for _ in range(N + 1)]     # Calling the dfs from node-0    dfs(0, visit)     return res     # Utility function to add an undirected edge (u,v)def addEdge(u: int, v: int) -> None:         global g     g[u].append(v)    g[v].append(u) #  Driver codeif __name__ == "__main__":     res = 0    edges = [ [ 0, 2 ], [ 0, 1 ],              [ 0, 4 ], [ 2, 3 ],              [ 4, 5 ], [ 5, 6 ],              [ 5, 7 ] ]    N = len(edges)    g = [[] for _ in range(N + 1)]         for i in range(N):        addEdge(edges[i][0], edges[i][1])     print(maxEdgeRemovalToMakeForestEven(N)) # This code is contributed by sanjeev2552
/* C# Program to get maximum number of edges whichcan be removed such that each connected componentof this tree will have an even number of vertices */using System;using System.Collections.Generic; class GFG{     // graphstatic List<List<int>> g = new List<List<int>>(); static int res; // Utility method to do DFS of the graph and// count edge deletion for even foreststatic int dfs( int u, bool []visit){    visit[u] = true;    int currComponentNode = 0;     // iterate over all neighbor of node u    for (int i = 0; i < g[u].Count; i++)    {        int v = g[u][i];        if (!visit[v])        {            // Count the number of nodes in a subtree            int subtreeNodeCount = dfs(v, visit);             // if returned node count is even, disconnect            // the subtree and increase result by one.            if (subtreeNodeCount % 2 == 0)                res++;             // else add subtree nodes in current component            else                currComponentNode += subtreeNodeCount;        }    }     // number of nodes in current component and one for    // current node    return (currComponentNode + 1);} /* method returns max edge that we can remove,after which each connected componentwill have even number of vertices */static int maxEdgeRemovalToMakeForestEven( int N){    // Create a visited array for DFS and    // make all nodes unvisited in starting    bool []visit = new bool[N + 1];    for (int i = 0; i <= N; i++)        visit[i] = false;     res = 0; // Passed as reference     // calling the dfs from node-0    dfs(0, visit);     return res;} // Utility function to add an undirected edge (u,v)static void addEdge( int u, int v){    g[u].Add(v);    g[v].Add(u);} // Driver codepublic static void Main(String []args){    int [,]edges = {{0, 2}, {0, 1}, {0, 4},                    {2, 3}, {4, 5}, {5, 6},                    {5, 7}};    int N = edges.GetLength(0);         for (int i = 0; i < N + 1; i++)    g.Add(new List<int>());         for (int i = 0; i < N; i++)        addEdge(edges[i, 0], edges[i, 1]);     Console.WriteLine(maxEdgeRemovalToMakeForestEven(N));}} // This code is contributed by 29AjayKumar
<script> /* Program to get maximum number of edges whichcan be removed such that each connected componentof this tree will have an even number of vertices */ // graphlet g = [];let res; // Utility method to do DFS of the graph and count edge// deletion for even forestfunction dfs(u,visit){    visit[u] = true;    let currComponentNode = 0;      // iterate over all neighbor of node u    for (let i = 0; i < g[u].length; i++)    {        let v = g[u][i];        if (!visit[v])        {            // Count the number of nodes in a subtree            let subtreeNodeCount = dfs(v, visit);              // if returned node count is even, disconnect            // the subtree and increase result by one.            if (subtreeNodeCount % 2 == 0)                res++;              // else add subtree nodes in current component            else                currComponentNode += subtreeNodeCount;        }    }      // number of nodes in current component and one for    // current node    return (currComponentNode + 1);} /* method returns max edge that we can remove, after which    each connected component will have even number of    vertices */function maxEdgeRemovalToMakeForestEven(N){    // Create a visited array for DFS and make all nodes    // unvisited in starting    let visit=new Array(N + 1);    for (let i = 0; i <= N; i++)        visit[i] = false;      res = 0; // Passed as reference      // calling the dfs from node-0    dfs(0, visit);      return res;} // Utility function to add an undirected edge (u,v)function addEdge(u,v){     g[u].push(v);    g[v].push(u);} // Driver code to test above methodslet edges=[[0, 2], [0, 1], [0, 4],                    [2, 3], [4, 5], [5, 6],                    [5, 7]];let N = edges.length;for (let i = 0; i < N+1; i++)    g.push([]); for (let i = 0; i < N; i++)    addEdge( edges[i][0], edges[i][1]);  document.write(maxEdgeRemovalToMakeForestEven( N)); // This code is contributed by rag2127 </script>
Output: 
2
Time Complexity: O(n) where n is number of nodes in tree.
This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@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. 
andrew1234
29AjayKumar
sanjeev2552
rag2127
DFS
Tree
DFS
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Inorder Tree Traversal without Recursion
Binary Tree | Set 3 (Types of Binary Tree)
Decision Tree
Binary Tree | Set 2 (Properties)
Complexity of different operations in Binary tree, Binary Search Tree and AVL tree
A program to check if a binary tree is BST or not
Construct Tree from given Inorder and Preorder traversals
Introduction to Tree Data Structure
Expression Tree
Deletion in a Binary Tree