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

`/* 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 forest` `int` `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 methods` `int` `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;` `}` |

## Java

`/* 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 */` `import` `java.util.*;` `class` `GFG` `{` ` ` `// graph` `static` `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 forest ` `static` `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 methods ` `public` `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

`# 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 vertices ` `from` `typing ` `import` `List` `# Utility method to do DFS of the graph` `# and count edge deletion for even forest` `def` `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 vertices` `def` `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 code ` `if` `__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#

`/* C# 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 */` `using` `System;` `using` `System.Collections.Generic;` `class` `GFG` `{` ` ` `// graph` `static` `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 forest ` `static` `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 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 ` ` ` `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 code` `public` `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` |

**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 contribute.geeksforgeeks.org or mail your article to contribute@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.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.