A tree is always a Bipartite Graph as we can always break into two disjoint sets with alternate levels. In other words we always color it with two colors such that alternate levels have same color. The task is to compute the maximum no. of edges that can be added to the tree so that it remains Bipartite Graph.
Examples:
Input : Tree edges as vertex pairs
1 2
1 3
Output : 0
Explanation :
The only edge we can add is from node 2 to 3.
But edge 2, 3 will result in odd cycle, hence
violation of Bipartite Graph property.
Input : Tree edges as vertex pairs
1 2
1 3
2 4
3 5
Output : 2
Explanation : On colouring the graph, {1, 4, 5}
and {2, 3} form two different sets. Since, 1 is
connected from both 2 and 3, we are left with
edges 4 and 5. Since, 4 is already connected to
2 and 5 to 3, only options remain {4, 3} and
{5, 2}.
- Do a simple DFS (or BFS) traversal of graph and color it with two colors.
- While coloring also keep track of counts of nodes colored with the two colors. Let the two counts be count_color0 and count_color1.
- Now we know maximum edges a bipartite graph can have are count_color0 x count_color1.
- We also know tree with n nodes has n-1 edges.
- So our answer is count_color0 x count_color1 – (n-1).
Below is the implementation :
C++
#include <bits/stdc++.h>
using namespace std;
long long count_color[2];
void dfs(vector< int > adj[], int node, int parent, int color)
{
count_color[color]++;
for ( int i = 0; i < adj[node].size(); i++) {
if (adj[node][i] != parent)
dfs(adj, adj[node][i], node, !color);
}
}
int findMaxEdges(vector< int > adj[], int n)
{
dfs(adj, 1, 0, 0);
return count_color[0] * count_color[1] - (n - 1);
}
int main()
{
int n = 5;
vector< int > adj[n + 1];
adj[1].push_back(2);
adj[1].push_back(3);
adj[2].push_back(4);
adj[3].push_back(5);
cout << findMaxEdges(adj, n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static long []count_color = new long [ 2 ];
static void dfs(Vector<Integer> adj[], int node,
int parent, boolean color)
{
count_color[color == false ? 0 : 1 ]++;
for ( int i = 0 ; i < adj[node].size(); i++)
{
if (adj[node].get(i) != parent)
dfs(adj, adj[node].get(i), node, !color);
}
}
static int findMaxEdges(Vector<Integer> adj[], int n)
{
dfs(adj, 1 , 0 , false );
return ( int ) (count_color[ 0 ] *
count_color[ 1 ] - (n - 1 ));
}
public static void main(String[] args)
{
int n = 5 ;
Vector<Integer>[] adj = new Vector[n + 1 ];
for ( int i = 0 ; i < n + 1 ; i++)
adj[i] = new Vector<Integer>();
adj[ 1 ].add( 2 );
adj[ 1 ].add( 3 );
adj[ 2 ].add( 4 );
adj[ 3 ].add( 5 );
System.out.println(findMaxEdges(adj, n));
}
}
|
Python3
def dfs(adj, node, parent, color):
count_color[color] + = 1
for i in range ( len (adj[node])):
if (adj[node][i] ! = parent):
dfs(adj, adj[node][i],
node, not color)
def findMaxEdges(adj, n):
dfs(adj, 1 , 0 , 0 )
return (count_color[ 0 ] *
count_color[ 1 ] - (n - 1 ))
count_color = [ 0 , 0 ]
n = 5
adj = [[] for i in range (n + 1 )]
adj[ 1 ].append( 2 )
adj[ 1 ].append( 3 )
adj[ 2 ].append( 4 )
adj[ 3 ].append( 5 )
print (findMaxEdges(adj, n))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static long []count_color = new long [2];
static void dfs(List< int > []adj, int node,
int parent, bool color)
{
count_color[color == false ? 0 : 1]++;
for ( int i = 0; i < adj[node].Count; i++)
{
if (adj[node][i] != parent)
dfs(adj, adj[node][i], node, !color);
}
}
static int findMaxEdges(List< int > []adj, int n)
{
dfs(adj, 1, 0, false );
return ( int ) (count_color[0] *
count_color[1] - (n - 1));
}
public static void Main(String[] args)
{
int n = 5;
List< int > []adj = new List< int >[n + 1];
for ( int i = 0; i < n + 1; i++)
adj[i] = new List< int >();
adj[1].Add(2);
adj[1].Add(3);
adj[2].Add(4);
adj[3].Add(5);
Console.WriteLine(findMaxEdges(adj, n));
}
}
|
Javascript
<script>
let count_color = new Array(2);
count_color.fill(0);
function dfs(adj, node, parent, color)
{
count_color[color == false ? 0 : 1]++;
for (let i = 0; i < adj[node].length; i++)
{
if (adj[node][i] != parent)
dfs(adj, adj[node][i], node, !color);
}
}
function findMaxEdges(adj, n)
{
dfs(adj, 1, 0, false );
return (count_color[0] * count_color[1] - (n - 1));
}
let n = 5;
let adj = [];
for (let i = 0; i < n + 1; i++)
adj.push([]);
adj[1].push(2);
adj[1].push(3);
adj[2].push(4);
adj[3].push(5);
document.write(findMaxEdges(adj, n));
</script>
|
Time Complexity: O(n)
This article is contributed by Rohit Thapliyal. 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.