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
#include <bits/stdc++.h>
using namespace std;
int dfs(vector< int > g[], int u, bool visit[], int & res)
{
visit[u] = true ;
int currComponentNode = 0;
for ( int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
if (!visit[v])
{
int subtreeNodeCount = dfs(g, v, visit, res);
if (subtreeNodeCount % 2 == 0)
res++;
else
currComponentNode += subtreeNodeCount;
}
}
return (currComponentNode + 1);
}
int maxEdgeRemovalToMakeForestEven(vector< int > g[], int N)
{
bool visit[N + 1];
for ( int i = 0; i <= N; i++)
visit[i] = false ;
int res = 0;
dfs(g, 0, visit, res);
return res;
}
void addEdge(vector< int > g[], int u, int v)
{
g[u].push_back(v);
g[v].push_back(u);
}
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
import java.util.*;
class GFG
{
static Vector<Vector<Integer>> g = new Vector<Vector<Integer>>();
static int res;
static int dfs( int u, boolean visit[])
{
visit[u] = true ;
int currComponentNode = 0 ;
for ( int i = 0 ; i < g.get(u).size(); i++)
{
int v = g.get(u).get(i);
if (!visit[v])
{
int subtreeNodeCount = dfs(v, visit);
if (subtreeNodeCount % 2 == 0 )
res++;
else
currComponentNode += subtreeNodeCount;
}
}
return (currComponentNode + 1 );
}
static int maxEdgeRemovalToMakeForestEven( int N)
{
boolean visit[]= new boolean [N + 1 ];
for ( int i = 0 ; i <= N; i++)
visit[i] = false ;
res = 0 ;
dfs( 0 , visit);
return res;
}
static void addEdge( int u, int v)
{
g.get(u).add(v);
g.get(v).add(u);
}
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));
}
}
|
Python3
from typing import List
def dfs(u: int , visit: List [ bool ]) - > int :
global res, g
visit[u] = True
currComponentNode = 0
for i in range ( len (g[u])):
v = g[u][i]
if ( not visit[v]):
subtreeNodeCount = dfs(v, visit)
if (subtreeNodeCount % 2 = = 0 ):
res + = 1
else :
currComponentNode + = subtreeNodeCount
return (currComponentNode + 1 )
def maxEdgeRemovalToMakeForestEven(N: int ) - > int :
visit = [ False for _ in range (N + 1 )]
dfs( 0 , visit)
return res
def addEdge(u: int , v: int ) - > None :
global g
g[u].append(v)
g[v].append(u)
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))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static List<List< int >> g = new List<List< int >>();
static int res;
static int dfs( int u, bool []visit)
{
visit[u] = true ;
int currComponentNode = 0;
for ( int i = 0; i < g[u].Count; i++)
{
int v = g[u][i];
if (!visit[v])
{
int subtreeNodeCount = dfs(v, visit);
if (subtreeNodeCount % 2 == 0)
res++;
else
currComponentNode += subtreeNodeCount;
}
}
return (currComponentNode + 1);
}
static int maxEdgeRemovalToMakeForestEven( int N)
{
bool []visit = new bool [N + 1];
for ( int i = 0; i <= N; i++)
visit[i] = false ;
res = 0;
dfs(0, visit);
return res;
}
static void addEdge( int u, int v)
{
g[u].Add(v);
g[v].Add(u);
}
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));
}
}
|
Javascript
<script>
let g = [];
let res;
function dfs(u,visit)
{
visit[u] = true ;
let currComponentNode = 0;
for (let i = 0; i < g[u].length; i++)
{
let v = g[u][i];
if (!visit[v])
{
let subtreeNodeCount = dfs(v, visit);
if (subtreeNodeCount % 2 == 0)
res++;
else
currComponentNode += subtreeNodeCount;
}
}
return (currComponentNode + 1);
}
function maxEdgeRemovalToMakeForestEven(N)
{
let visit= new Array(N + 1);
for (let i = 0; i <= N; i++)
visit[i] = false ;
res = 0;
dfs(0, visit);
return res;
}
function addEdge(u,v)
{
g[u].push(v);
g[v].push(u);
}
let 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));
</script>
|
Output:
2
Time Complexity: O(n) where n is number of nodes in tree.
Auxiliary Space: O(n)
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.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
10 Mar, 2023
Like Article
Save Article