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

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.`

## Javascript

 `// JavaScript code for the above approach:`   `// DFS to mark nodes as black or white.` `const dfs = (node, par, isBlack, adj, color) => {` `  ``// Mark color as black or white.` `  ``color[node] = isBlack;`   `  ``for` `(let 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);` `  ``}` `};`   `// Function to calculate` `// maximum number of edges` `// that can be added` `const maxEdges = (n, edges) => {` `  ``// Build adjacency matrix.` `  ``const adj = Array.from({ length: n + 1 }, () =>` `Array.from({ length: n + 1 }, () => 0)` `  ``);` `  ``edges.forEach(([a, b]) => {` `adj[a][b] = 1;` `adj[b][a] = 1;` `  ``});`   `  ``// Call DFS to color nodes.` `  ``const color = Array.from({ length: n + 1 }, () => ``false``);` `  ``dfs(1, 0, ``true``, adj, color);`   `  ``let ans = 0;`   `  ``// Iterate over all pairs of nodes.` `  ``for` `(let i = 1; i <= n; i++) {` `for` `(let 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` `const N = 4;` `const edges = [[1, 2], [2, 3], [1, 4]];` `console.log(maxEdges(N, edges));`   `// This code is contributed by Aman Kumar.`

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[0]].Add(edge[1]);`   `      ``adj[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.` `  ``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)`

## Javascript

 `       ``// JavaScript code for the above approach` `       ``// DFS to count number of black nodes.` `       ``function` `dfs(node, par, isBlack, adj) {` `           ``let no_Of_Black = isBlack ? 1 : 0;` `           ``for` `(let i of 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` `       ``function` `maxEdges(n, edges) {` `           ``// Build adjacency list.` `           ``let adj = ``new` `Array(n + 1);` `           ``for` `(let i = 0; i <= n; i++) {` `               ``adj[i] = [];` `           ``}` `           ``for` `(let i of edges) {` `               ``adj[i[0]].push(i[1]);` `               ``adj[i[1]].push(i[0]);` `           ``}`   `           ``// Number of black nodes.` `           ``let no_Of_Black = dfs(1, 0, ``true``, adj);`   `           ``// Number of white nodes.` `           ``let 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` `       ``let N = 4;` `       ``let edges = [[1, 2], [2, 3], [1, 4]];` `       ``console.log(maxEdges(N, edges));`   `// This code is contributed by Potta Lokesh`

Output

`1`

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

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!

Previous
Next