# 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)

My Personal Notes arrow_drop_up