Skip to content
Related Articles
Shortest path in a complement graph
• Difficulty Level : Hard
• Last Updated : 28 Jan, 2021

Given an undirected non-weighted graph G. For a given node start return the shortest path that is the number of edges from start to all the nodes in the complement graph of G.

Complement Graph is a graph such that it contains only those edges which are not present in the original graph.

Examples:

Input: Undirected Edges = (1, 2), (1, 3), (3, 4), (3, 5), Start = 1
Output: 0 2 3 1 1
Explanation:
Original Graph: Complement Graph: The distance from 1 to every node in the complement graph are:
1 to 1 = 0,
1 to 2 = 2,
1 to 3 = 3,
1 to 4 = 1,
1 to 5 = 1

Naive Approach: A Simple solution will be to create the complement graph and use Breadth-First Search on this graph to find the distance to all the nodes.
Time complexity: O(n2) for creating the complement graph and O(n + m) for breadth first search.
Efficient Approach: The idea is to use Modified Breadth-First Search to calculate the answer and then there is no need to construct the complement graph.

• For each vertex or node, reduce the distance of a vertex which is a complement to the current vertex and has not been discovered yet.
• For the problem, we have to observe that if the Graph is Sparse then the undiscovered nodes will be visited very fast.

Below is the implementation of the above approach:

## C++

 `// C++ implementation to find the``// shortest path in a complement graph` `#include ``using` `namespace` `std;` `const` `int` `inf = 100000;` `void` `bfs(``int` `start, ``int` `n, ``int` `m,``         ``map, ``int``> edges)``{``    ``int` `i;` `    ``// List of undiscovered vertices``    ``// initially it will contain all``    ``// the vertices of the graph``    ``set<``int``> undiscovered;` `    ``// Distance will store the distance``    ``// of all vertices from start in the``    ``// complement graph``    ``vector<``int``> distance_node(10000);` `    ``for` `(i = 1; i <= n; i++) {` `        ``// All vertices are undiscovered``        ``undiscovered.insert(i);` `        ``// Let initial distance be infinity``        ``distance_node[i] = inf;``    ``}` `    ``undiscovered.erase(start);``    ``distance_node[start] = 0;``    ``queue<``int``> q;` `    ``q.push(start);` `    ``// Check if queue is not empty and the``    ``// size of undiscovered vertices``    ``// is greater than 0``    ``while` `(undiscovered.size() && !q.empty()) {``        ``int` `cur = q.front();``        ``q.pop();` `        ``// Vector to store all the complement``        ``// vertex to the current vertex``        ``// which has not been``        ``// discovered or visited yet.``        ``vector<``int``> complement_vertex;` `        ``for` `(``int` `x : undiscovered) {``          ` `            ``if` `(edges.count({ cur, x }) == 0 &&``                ``edges.count({ x, cur })==0)``                ``complement_vertex.push_back(x);``        ``}``        ``for` `(``int` `x : complement_vertex) {` `            ``// Check if optimal change``            ``// the distance of this``            ``// complement vertex``            ``if` `(distance_node[x]``                ``> distance_node[cur] + 1) {``                ``distance_node[x]``                    ``= distance_node[cur] + 1;``                ``q.push(x);``            ``}` `            ``// Finally this vertex has been``            ``// discovered so erase it from``            ``// undiscovered vertices list``            ``undiscovered.erase(x);``        ``}``    ``}``    ``// Print the result``    ``for` `(``int` `i = 1; i <= n; i++)``        ``cout << distance_node[i] << ``" "``;``}` `// Driver code``int` `main()``{``    ``// n is the number of vertex``    ``// m is the number of edges``    ``// start - starting vertex is 1``    ``int` `n = 5, m = 4;` `    ``// Using edge hashing makes the``    ``// algorithm faster and we can``    ``// avoid the use of adjacency``    ``// list representation``    ``map, ``int``> edges;` `    ``// Initial edges for``    ``// the original graph``    ``edges[{ 1, 3 }] = 1,``                 ``edges[{ 3, 1 }] = 1;``    ``edges[{ 1, 2 }] = 1,``                 ``edges[{ 2, 1 }] = 1;``    ``edges[{ 3, 4 }] = 1,``                 ``edges[{ 4, 3 }] = 1;``    ``edges[{ 3, 5 }] = 1,``                 ``edges[{ 5, 3 }] = 1;` `    ``bfs(1, n, m, edges);` `    ``return` `0;``}`

## Java

 `// Java implementation to find the``// shortest path in a complement graph``import` `java.io.*;``import` `java.util.*;` `class` `GFG{``    ` `// Pair class is made so as to``// store the edges between nodes``static` `class` `Pair``{``    ``int` `left;``    ``int` `right;``    ` `    ``public` `Pair(``int` `left, ``int` `right)``    ``{``        ``this``.left = left;``        ``this``.right = right;``    ``}``    ` `    ``// We need to override hashCode so that``    ``// we can use Set's properties like contains()``    ``@Override``    ``public` `int` `hashCode()``    ``{``        ``final` `int` `prime = ``31``;``        ``int` `result = ``1``;``        ``result = prime * result + left;``        ``result = prime * result + right;``        ``return` `result;``    ``}` `    ``@Override``    ``public` `boolean` `equals( Object other )``    ``{``        ``if` `(``this` `== other){``return` `true``;}``        ``if` `(other ``instanceof` `Pair)``        ``{``            ``Pair m = (Pair)other;``            ``return` `this``.left == m.left &&``                  ``this``.right == m.right;``        ``}``        ``return` `false``;``    ``}``}` `public` `static` `void` `bfs(``int` `start, ``int` `n, ``int` `m,``                       ``Set edges)``{``    ``int` `i;` `    ``// List of undiscovered vertices``    ``// initially it will contain all``    ``// the vertices of the graph``    ``Set undiscovered = ``new` `HashSet<>();` `    ``// Distance will store the distance``    ``// of all vertices from start in the``    ``// complement graph``    ``int``[] distance_node = ``new` `int``[``1000``];` `    ``for``(i = ``1``; i <= n; i++)``    ``{` `        ``// All vertices are undiscovered initially``        ``undiscovered.add(i);` `        ``// Let initial distance be maximum value``        ``distance_node[i] = Integer.MAX_VALUE;``    ``}``    ` `    ``// Start is discovered``    ``undiscovered.remove(start);``    ` `    ``// Distance of the node to itself is 0``    ``distance_node[start] = ``0``;``    ` `    ``// Queue used for BFS``    ``Queue q = ``new` `LinkedList<>();` `    ``q.add(start);` `    ``// Check if queue is not empty and the``    ``// size of undiscovered vertices``    ``// is greater than 0``    ``while` `(undiscovered.size() > ``0` `&& !q.isEmpty())``    ``{``        ` `        ``// Current node``        ``int` `cur = q.peek();``        ``q.remove();` `        ``// Vector to store all the complement``        ``// vertex to the current vertex``        ``// which has not been``        ``// discovered or visited yet.``        ``Listcomplement_vertex = ``new` `ArrayList<>();` `        ``for``(``int` `x : undiscovered)``        ``{``            ``Pair temp1 = ``new` `Pair(cur, x);``            ``Pair temp2 = ``new` `Pair(x, cur);``            ` `            ``// Add the edge if not already present``            ``if` `(!edges.contains(temp1) &&``                ``!edges.contains(temp2))``            ``{``                ``complement_vertex.add(x);``            ``}``        ``}``        ` `        ``for``(``int` `x : complement_vertex)``        ``{``            ` `            ``// Check if optimal change``            ``// the distance of this``            ``// complement vertex``            ``if` `(distance_node[x] >``                ``distance_node[cur] + ``1``)``            ``{``                ``distance_node[x] =``                ``distance_node[cur] + ``1``;``                ``q.add(x);``            ``}` `            ``// Finally this vertex has been``            ``// discovered so erase it from``            ``// undiscovered vertices list``            ``undiscovered.remove(x);``        ``}``    ``}``    ` `    ``// Print the result``    ``for``(i = ``1``; i <= n; i++)``        ``System.out.print(distance_node[i] + ``" "``);``}``    ` `// Driver code``public` `static` `void` `main(String[] args)``{``    ` `    ``// n is the number of vertex``    ``// m is the number of edges``    ``// start - starting vertex is 1``    ``int` `n = ``5``, m = ``4``;` `    ``// Using edge hashing makes the``    ``// algorithm faster and we can``    ``// avoid the use of adjacency``    ``// list representation``    ``Set edges = ``new` `HashSet<>();` `    ``// Initial edges for``    ``// the original graph``    ``edges.add(``new` `Pair(``1``, ``3``));``    ``edges.add(``new` `Pair(``3``, ``1``));``    ``edges.add(``new` `Pair(``1``, ``2``));``    ``edges.add(``new` `Pair(``2``, ``1``));``    ``edges.add(``new` `Pair(``3``, ``4``));``    ``edges.add(``new` `Pair(``4``, ``3``));``    ``edges.add(``new` `Pair(``3``, ``5``)) ;``    ``edges.add(``new` `Pair(``5``, ``3``));``    ``Pair t = ``new` `Pair(``1``, ``3``);` `    ``bfs(``1``, n, m, edges);``}``}` `// This code is contributed by kunalsg18elec`
Output:
`0 2 3 1 1`

Time complexity: O(V+E)
Auxiliary Space: O(V)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer Geeks Classes Live

My Personal Notes arrow_drop_up