 GFG App
Open App Browser
Continue

# 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].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)`

## 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].push(i);` `               ``adj[i].push(i);` `           ``}`   `           ``// 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)

My Personal Notes arrow_drop_up