# Maximize number of edges added to convert given Tree into a Bipartite Graph

• Difficulty Level : Medium
• Last Updated : 20 Jun, 2022

Given a tree of N nodes, the task is to find the maximum number of edges that can be added to the tree such that it becomes a bipartite graph.

Note: Self loop or multiple edges are not allowed but cycles are permitted.

Examples:

Input: N = 4, Edges = {{1, 2}, {2, 3}, {1, 4}}
1
/    \
2       4
/
3
Output: 1
Explanation: An edge between nodes 3 and 4 can be added such that the graph still remains bipartite.
No more than 1 edge can be added such that the resultant graph is bipartite.

Input: N = 5, Edges = {{1, 2}, {1, 3}, {2, 4}, {2, 5}}
1
/    \
2        3
/     \
4         5
Output: 2
Explanation: Two edges can be added, (3, 4) and (3, 5) and the graph still remains bipartite.

Naive Approach: The basic way to solve the problem is as follows:

Assign each node of the tree as black or white such that a black node is connected with a white node (There is always such a configuration because a tree is always bipartite).
Then for all possible pair of nodes check if an edge can be added between them.

Follow the steps mentioned below to implement the above idea:

• Traverse the tree initially and assign each node as black or white such that each edge connects a black and a white node. (Trees are always bipartite).
• Iterate over all pairs of nodes, and check if an edge can be added between them.
• If both the nodes are of different colors and there is no edge between them, an edge can be added. So increment the count.
• Otherwise, no edge can be added.
• The final value of count is the answer.

Below is the implementation of the above approach.

## C++

 `// C++ code for the above approach:` `#include ``using` `namespace` `std;` `// DFS to mark nodes as black or white.``void` `dfs(``int` `node, ``int` `par, ``bool` `isBlack,``         ``vector >& adj,``         ``vector<``bool``>& color)``{` `    ``// Mark color as black or white.``    ``color[node] = isBlack;` `    ``for` `(``int` `i = 1; i < adj.size(); ++i) {` `        ``// If there is no edge,``        ``// or 'i' is parent, continue.``        ``if` `(!adj[node][i] || i == par)``            ``continue``;` `        ``dfs(i, node, !isBlack, adj, color);``    ``}``}` `// Function to calculate``// maximum number of edges``// that can be added``long` `long` `maxEdges(``int` `n,``                   ``vector > edges)``{` `    ``// Build adjacency matrix.``    ``vector > adj(n + 1,``                              ``vector<``bool``>(``                                  ``n + 1, 0));``    ``for` `(``auto` `i : edges) {``        ``adj[i.first][i.second] = 1;``        ``adj[i.second][i.first] = 1;``    ``}` `    ``// Call DFS to color nodes.``    ``vector<``bool``> color(n + 1);``    ``dfs(1, 0, 1, adj, color);` `    ``long` `long` `ans = 0;` `    ``// Iterate over all pairs of nodes.``    ``for` `(``int` `i = 1; i <= n; ++i) {``        ``for` `(``int` `j = i + 1; j <= n; ++j) {` `            ``// If the color is different``            ``// And there is no edge``            ``// Between them, increment answer.``            ``if` `(color[i] != color[j]``                ``&& !adj[i][j])``                ``ans++;``        ``}``    ``}` `    ``// Return answer.``    ``return` `ans;``}` `// Driver Code``int` `main()``{``    ``int` `N = 4;``    ``vector > edges``        ``= { { 1, 2 }, { 2, 3 }, { 1, 4 } };``    ``cout << maxEdges(N, edges);``    ``return` `0;``}`

## Java

 `// Java code for the above approach:``import` `java.util.*;` `public` `class` `Main {``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `N = ``4``;``    ``List > edges = ``new` `ArrayList<>();``    ``edges.add(Arrays.asList(``1``, ``2``));``    ``edges.add(Arrays.asList(``2``, ``3``));``    ``edges.add(Arrays.asList(``1``, ``4``));``    ``System.out.println(maxEdges(N, edges));``  ``}``  ``// Function to calculate``  ``// maximum number of edges``  ``// that can be added``  ``public` `static` `long` `maxEdges(``int` `n,``                              ``List > edges)``  ``{``    ``// Build adjacency matrix.``    ``boolean``[][] adj = ``new` `boolean``[n + ``1``][n + ``1``];``    ``for` `(``int` `i = ``0``; i < edges.size(); ++i) {``      ``adj[edges.get(i).get(``0``)][edges.get(i).get(``1``)]``        ``= ``true``;``      ``adj[edges.get(i).get(``1``)][edges.get(i).get(``0``)]``        ``= ``true``;``    ``}``    ``// Call DFS to color nodes.``    ``boolean``[] color = ``new` `boolean``[n + ``1``];``    ``dfs(``1``, ``0``, ``true``, adj, color);` `    ``long` `ans = ``0``;``    ``// Iterate over all pairs of nodes.``    ``for` `(``int` `i = ``1``; i <= n; ++i) {``      ``for` `(``int` `j = i + ``1``; j <= n; ++j) {``        ``// If the color is different``        ``// And there is no edge``        ``// Between them, increment answer.``        ``if` `(color[i] != color[j] && !adj[i][j])``          ``ans++;``      ``}``    ``}``    ``// return ans``    ``return` `ans;``  ``}``  ``// DFS to mark nodes as black or white.``  ``public` `static` `void` `dfs(``int` `node, ``int` `par,``                         ``boolean` `isBlack, ``boolean``[][] adj,``                         ``boolean``[] color)``  ``{``    ` `    ``// Mark color as black or white.``    ``color[node] = isBlack;` `    ``for` `(``int` `i = ``1``; i < adj.length; ++i)``    ``{``      ` `      ``// If there is no edge,``      ``// or 'i' is parent, continue.``      ``if` `(!adj[node][i] || i == par)``        ``continue``;` `      ``dfs(i, node, !isBlack, adj, color);``    ``}``  ``}``}` `// This code is contributed by Tapesh(tapeshdua420)`

## Python3

 `#  Python code for the above approach:` `# DFS to mark nodes as black or white.``def` `dfs(node, par, isBlack, adj, color):` `  ``# Mark color as black or white.``    ``color[node] ``=` `isBlack``    ``for` `i ``in` `range``(``1``, ``len``(adj)):``        ``# If there is no edge,``         ``# or 'i' is parent, continue.``        ``if` `not` `adj[node][i] ``or` `i ``=``=` `par:``            ``continue``        ``dfs(i, node, ``not` `isBlack, adj, color)` `# Function to calculate``# maximum number of edges``# that can be added``def` `maxEdges(n, edges):``  ` `  ``# Build adjacency matrix.``    ``adj ``=` `[[``0` `for` `_ ``in` `range``(n ``+` `1``)] ``for` `_ ``in` `range``(n ``+` `1``)]``    ``for` `i ``in` `edges:``        ``adj[i[``0``]][i[``1``]] ``=` `1``        ``adj[i[``1``]][i[``0``]] ``=` `1` `    ``# Call DFS to color nodes.``    ``color ``=` `[``0` `for` `_ ``in` `range``(n ``+` `1``)]``    ``dfs(``1``, ``0``, ``1``, adj, color)` `    ``ans ``=` `0` `    ``# Iterate over all pairs of nodes.``    ``for` `i ``in` `range``(``1``, n ``+` `1``):``        ``for` `j ``in` `range``(i ``+` `1``, n ``+` `1``):``                ``# If the color is different``            ``# And there is no edge``            ``# Between them, increment answer.``            ``if` `color[i] !``=` `color[j] ``and` `not` `adj[i][j]:``                ``ans ``+``=` `1``        ``# Return answer.``    ``return` `ans`  `# Driver Code``N ``=` `4``edges ``=` `[[``1``, ``2``], [``2``, ``3``], [``1``, ``4``]]``print``(maxEdges(N, edges))` `# This code is contributed by tapeshdua420.`

## C#

 `// C# code for the above approach:``using` `System;``using` `System.Collections.Generic;``using` `System.Linq;``class` `Program {``    ``static` `void` `Main(``string``[] args)``    ``{``        ``int` `N = 4;``        ``List > edges``            ``= ``new` `List >(N);``        ``edges.Add(``new` `Tuple<``int``, ``int``>(1, 2));``        ``edges.Add(``new` `Tuple<``int``, ``int``>(2, 3));``        ``edges.Add(``new` `Tuple<``int``, ``int``>(1, 4));``        ``Console.WriteLine(maxEdges(N, edges));``    ``}``  ` `    ``// DFS to mark nodes as black or white.``    ``static` `void` `dfs(``int` `node, ``int` `par, ``bool` `isBlack,``                    ``bool``[, ] adj, ``bool``[] color)``    ``{``      ` `        ``// Mark color as black or white.``        ``color[node] = isBlack;` `        ``for` `(``int` `i = 1; i < adj.GetLength(0); i++)``        ``{``          ` `            ``// If there is no edge,``            ``// or 'i' is parent, continue.``            ``if` `(adj[node, i] == ``false` `|| i == par)``                ``continue``;``            ``dfs(i, node, !isBlack, adj, color);``        ``}``    ``}``  ` `    ``// Function to calculate``    ``// maximum number of edges``    ``// that can be added``    ``static` `long` `maxEdges(``int` `n,``                         ``List > edges)``    ``{``      ` `        ``// Build adjacency matrix.``        ``bool``[, ] adj = ``new` `bool``[n + 1, n + 1];` `        ``foreach``(Tuple<``int``, ``int``> tuple ``in` `edges)``        ``{``            ``adj[tuple.Item1, tuple.Item2] = ``true``;``            ``adj[tuple.Item2, tuple.Item1] = ``true``;``        ``}` `        ``// Call DFS to color nodes.``        ``bool``[] color = ``new` `bool``[n + 1];``        ``dfs(1, 0, ``true``, adj, color);` `        ``long` `ans = 0;` `        ``// Iterate over all pairs of nodes.``        ``for` `(``int` `i = 1; i <= n; ++i)``        ``{``            ``for` `(``int` `j = i + 1; j <= n; ++j)``            ``{``              ` `                ``// If the color is different``                ``// And there is no edge``                ``// Between them, increment answer.``                ``if` `(color[i] != color[j]``                    ``&& adj[i, j] == ``false``)``                    ``ans++;``            ``}``        ``}``      ` `        ``// Return answer.``        ``return` `ans;``    ``}``}` `// This code is contributed by tapeshdua420.`

Output

`1`

Time Complexity: O(N2)
Auxiliary Space: O(N2)

Efficient Approach: The time taken in the above approach can be optimized by using the following observation:

Say, there were initially B black nodes and W white nodes in the tree. So a bipartite graph made from these nodes can have maximum B*W edges.
Therefore, the maximum number of edges that can be added to the tree with N nodes are B*W – (N-1) [as a tree with N node has N-1 edges]

• Traverse the tree initially and assign each node as black or white such that each edge connects a black and a white node. (Trees are always bipartite).
• Count the number of black nodes and white nodes.
• Use the formula derived above from the observation and calculate the maximum number of edges that can be added.

Below is the implementation of the above approach.

## C++

 `// C++ code for the above approach:` `#include ``using` `namespace` `std;` `// DFS to count number of black nodes.``int` `dfs(``int` `node, ``int` `par, ``bool` `isBlack,``        ``vector >& adj)``{``    ``int` `no_Of_Black = isBlack;``    ``for` `(``int` `i : adj[node]) {``        ``if` `(i == par)``            ``continue``;` `        ``// Number of black nodes``        ``// in each subtree.``        ``no_Of_Black``            ``+= dfs(i, node, !isBlack, adj);``    ``}``    ``return` `no_Of_Black;``}` `// Function to find maximum edges``long` `long` `maxEdges(``int` `n,``                   ``vector > edges)``{` `    ``// Build adjacency list.``    ``vector > adj(n + 1);``    ``for` `(``auto` `i : edges) {``        ``adj[i.first].push_back(i.second);``        ``adj[i.second].push_back(i.first);``    ``}` `    ``// Number of black nodes.``    ``int` `no_Of_Black = dfs(1, 0, 1, adj);` `    ``// Number of white nodes.``    ``int` `no_Of_White = n - no_Of_Black;` `    ``// Number of edges that can be added.``    ``return` `(1LL * (no_Of_Black)``                ``* (no_Of_White)``            ``- (n - 1));``}` `// Driver code``int` `main()``{``    ``int` `N = 4;``    ``vector > edges``        ``= { { 1, 2 }, { 2, 3 }, { 1, 4 } };``    ``cout << maxEdges(N, edges);``    ``return` `0;``}`

## Java

 `// Java code for the above approach:``import` `java.util.*;` `public` `class` `Main``{` `  ``// Driver code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `N = ``4``;``    ``int``[][] edges = { { ``1``, ``2` `}, { ``2``, ``3` `}, { ``1``, ``4` `} };``    ``System.out.println(maxEdges(N, edges));``  ``}` `  ``// Function to find maximum edges``  ``public` `static` `long` `maxEdges(``int` `n, ``int``[][] edges)``  ``{``    ``// Build adjacency list.``    ``List > adj = ``new` `ArrayList<>();``    ``for` `(``int` `i = ``0``; i <= n; i++) {``      ``adj.add(``new` `ArrayList<>());``    ``}``    ``for` `(``int``[] edge : edges) {``      ``adj.get(edge[``0``]).add(edge[``1``]);``      ``adj.get(edge[``1``]).add(edge[``0``]);``    ``}``    ``// Number of black nodes.``    ``int` `no_Of_Black = dfs(``1``, ``0``, ``true``, adj);` `    ``// Number of white nodes.``    ``int` `no_Of_White = n - no_Of_Black;` `    ``// Number of edges that can be added.``    ``return` `((no_Of_Black) * (no_Of_White) - (n - ``1``));``  ``}` `  ``// DFS to count number of black nodes.``  ``public` `static` `int` `dfs(``int` `node, ``int` `par,``                        ``boolean` `isBlack,``                        ``List > adj)``  ``{` `    ``int` `no_Of_Black = (isBlack == ``true``) ? ``1` `: ``0``;` `    ``for` `(``int` `i : adj.get(node)) {` `      ``if` `(i == par)``        ``continue``;` `      ``// Number of black nodes``      ``// in each subtree.``      ``no_Of_Black += dfs(i, node, !isBlack, adj);``    ``}``    ``return` `no_Of_Black;``  ``}``}` `// This code is contributed by Tapesh(tapeshdua420)`

## Python3

 `## DFS to count number of black nodes.``def` `dfs(node, par, isBlack, adj) :``    ``no_of_black ``=` `isBlack``    ``for` `i ``in` `adj[node]:``        ``if``(i``=``=``par):``            ``continue``        ` `        ``## Number of black nodes``        ``## in each subtree.``        ``no_of_black ``+``=` `dfs(i, node, (``not` `isBlack), adj)` `    ``return` `no_of_black`  `def` `maxEdges(n, edges):``    ``adj ``=` `[]``    ` `    ``for` `i ``in` `range``(n``+``1``):``        ``adj.append(``list``())``    ` `    ``## Create the graph``    ``## From the given input.``    ``for` `i ``in` `edges:``        ``adj[i[``0``]].append(i[``1``])``        ``adj[i[``1``]].append(i[``0``])` `    ``## Number of black nodes.``    ``no_of_black ``=` `dfs(``1``, ``0``, ``1``, adj)` `    ``## Number of white nodes.``    ``no_of_white ``=` `n ``-` `no_of_black` `    ``## Number of edges that can be added.``    ``return` `(no_of_black``*``no_of_white) ``-` `(n``-``1``)``    ` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:` `    ``N ``=` `4``    ``edges ``=` `list``((``list``((``1``, ``2``)), ``list``((``2``, ``3``)), ``list``((``1``, ``4``))))` `    ``print``(maxEdges(N, edges))``    ` `    ``# This code is contributed by subhamgoyal2014.`

## C#

 `// C# code for the above approach:``using` `System;``using` `System.Collections.Generic;` `class` `Program {` `  ``// Driver code``  ``static` `void` `Main(``string``[] args)``  ``{` `    ``int` `N = 4;` `    ``int``[][] edges``      ``= { ``new` `int``[] { 1, 2 }, ``new` `int``[] { 2, 3 },``         ``new` `int``[] { 1, 4 } };` `    ``Console.WriteLine(maxEdges(N, edges));``  ``}` `  ``// Function to find maximum edges``  ``static` `long` `maxEdges(``int` `n, ``int``[][] edges)``  ``{` `    ``// Build adjacency list.``    ``List > adj = ``new` `List >();` `    ``for` `(``int` `i = 0; i <= n; i++) {``      ``adj.Add(``new` `List<``int``>());``    ``}` `    ``foreach``(``int``[] edge ``in` `edges)``    ``{` `      ``adj[edge].Add(edge);` `      ``adj[edge].Add(edge);``    ``}` `    ``// Number of black nodes.``    ``int` `no_Of_Black = dfs(1, 0, ``true``, adj);` `    ``// Number of white nodes.``    ``int` `no_Of_White = n - no_Of_Black;` `    ``// Number of edges that can be added.``    ``return` `((no_Of_Black) * (no_Of_White) - (n - 1));``  ``}` `  ``// DFS to count number of black nodes.``  ``static` `int` `dfs(``int` `node, ``int` `par, ``bool` `isBlack,``                 ``List > adj)``  ``{` `    ``int` `no_Of_Black = (isBlack == ``true``) ? 1 : 0;` `    ``foreach``(``int` `i ``in` `adj[node])``    ``{` `      ``if` `(i == par)``        ``continue``;` `      ``// Number of black nodes``      ``// in each subtree.``      ``no_Of_Black += dfs(i, node, !isBlack, adj);``    ``}``    ``return` `no_Of_Black;``  ``}``}` `// This code is contributed by Tapesh (tapeshdua420)`

Output

`1`

Time Complexity: O(N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up