Given an undirected and unweighted graph and two nodes as source and destination, the task is to print all the paths of the shortest length between the given source and destination.
Examples:
Input: source = 0, destination = 5
Output:
0 -> 1 -> 3 -> 5
0 -> 2 -> 3 -> 5
0 -> 1 -> 4 -> 5
Explanation:
All the above paths are of length 3, which is the shortest distance between 0 and 5.
Input: source = 0, destination = 4
Output:
0 -> 1 -> 4
Approach: The is to do a Breadth First Traversal (BFS) for a graph. Below are the steps:
- Start BFS traversal from source vertex.
- While doing BFS, store the shortest distance to each of the other nodes and also maintain a parent vector for each of the nodes.
- Make the parent of source node as “-1”. For each node, it will store all the parents for which it has the shortest distance from the source node.
- Recover all the paths using parent array. At any instant, we will push one vertex in the path array and then call for all its parents.
- If we encounter “-1” in the above steps, then it means a path has been found and can be stored in the paths array.
Below is the implementation of the above approach:
// Cpp program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to form edge between // two vertices src and dest void add_edge(vector< int > adj[],
int src, int dest)
{ adj[src].push_back(dest);
adj[dest].push_back(src);
} // Function which finds all the paths // and stores it in paths array void find_paths(vector<vector< int > >& paths,
vector< int >& path,
vector< int > parent[],
int n, int u)
{ // Base Case
if (u == -1) {
paths.push_back(path);
return ;
}
// Loop for all the parents
// of the given vertex
for ( int par : parent[u]) {
// Insert the current
// vertex in path
path.push_back(u);
// Recursive call for its parent
find_paths(paths, path, parent,
n, par);
// Remove the current vertex
path.pop_back();
}
} // Function which performs bfs // from the given source vertex void bfs(vector< int > adj[],
vector< int > parent[],
int n, int start)
{ // dist will contain shortest distance
// from start to every other vertex
vector< int > dist(n, INT_MAX);
queue< int > q;
// Insert source vertex in queue and make
// its parent -1 and distance 0
q.push(start);
parent[start] = { -1 };
dist[start] = 0;
// Until Queue is empty
while (!q.empty()) {
int u = q.front();
q.pop();
for ( int v : adj[u]) {
if (dist[v] > dist[u] + 1) {
// A shorter distance is found
// So erase all the previous parents
// and insert new parent u in parent[v]
dist[v] = dist[u] + 1;
q.push(v);
parent[v].clear();
parent[v].push_back(u);
}
else if (dist[v] == dist[u] + 1) {
// Another candidate parent for
// shortes path found
parent[v].push_back(u);
}
}
}
} // Function which prints all the paths // from start to end void print_paths(vector< int > adj[],
int n, int start, int end)
{ vector<vector< int > > paths;
vector< int > path;
vector< int > parent[n];
// Function call to bfs
bfs(adj, parent, n, start);
// Function call to find_paths
find_paths(paths, path, parent, n, end);
for ( auto v : paths) {
// Since paths contain each
// path in reverse order,
// so reverse it
reverse(v.begin(), v.end());
// Print node for the current path
for ( int u : v)
cout << u << " " ;
cout << endl;
}
} // Driver Code int main()
{ // Number of vertices
int n = 6;
// array of vectors is used
// to store the graph
// in the form of an adjacency list
vector< int > adj[n];
// Given Graph
add_edge(adj, 0, 1);
add_edge(adj, 0, 2);
add_edge(adj, 1, 3);
add_edge(adj, 1, 4);
add_edge(adj, 2, 3);
add_edge(adj, 3, 5);
add_edge(adj, 4, 5);
// Given source and destination
int src = 0;
int dest = n - 1;
// Function Call
print_paths(adj, n, src, dest);
return 0;
} |
/*package whatever //do not write package name here */ import java.io.*;
import java.util.*;
class GFG {
// Function to form edge between
// two vertices src and dest
static void add_edge(ArrayList<ArrayList<Integer>> adj, int src, int dest){
adj.get(src).add(dest);
adj.get(dest).add(src);
}
// Function which finds all the paths
// and stores it in paths array
static void find_paths(ArrayList<ArrayList<Integer>> paths, ArrayList<Integer> path,
ArrayList<ArrayList<Integer>> parent, int n, int u) {
// Base Case
if (u == - 1 ) {
paths.add( new ArrayList<>(path));
return ;
}
// Loop for all the parents
// of the given vertex
for ( int par : parent.get(u)) {
// Insert the current
// vertex in path
path.add(u);
// Recursive call for its parent
find_paths(paths, path, parent, n, par);
// Remove the current vertex
path.remove(path.size()- 1 );
}
}
// Function which performs bfs
// from the given source vertex
static void bfs(ArrayList<ArrayList<Integer>> adj, ArrayList<ArrayList<Integer>> parent,
int n, int start) {
// dist will contain shortest distance
// from start to every other vertex
int [] dist = new int [n];
Arrays.fill(dist, Integer.MAX_VALUE);
Queue<Integer> q = new LinkedList<>();
// Insert source vertex in queue and make
// its parent -1 and distance 0
q.offer(start);
parent.get(start).clear();
parent.get(start).add(- 1 );
dist[start] = 0 ;
// Until Queue is empty
while (!q.isEmpty()) {
int u = q.poll();
for ( int v : adj.get(u)) {
if (dist[v] > dist[u] + 1 ) {
// A shorter distance is found
// So erase all the previous parents
// and insert new parent u in parent[v]
dist[v] = dist[u] + 1 ;
q.offer(v);
parent.get(v).clear();
parent.get(v).add(u);
}
else if (dist[v] == dist[u] + 1 ) {
// Another candidate parent for
// shortes path found
parent.get(v).add(u);
}
}
}
}
// Function which prints all the paths
// from start to end
static void print_paths(ArrayList<ArrayList<Integer>> adj, int n, int start, int end){
ArrayList<ArrayList<Integer>> paths = new ArrayList<>();
ArrayList<Integer> path = new ArrayList<>();
ArrayList<ArrayList<Integer>> parent = new ArrayList<>();
for ( int i = 0 ; i < n; i++){
parent.add( new ArrayList<>());
}
// Function call to bfs
bfs(adj, parent, n, start);
// Function call to find_paths
find_paths(paths, path, parent, n, end);
for (ArrayList<Integer> v : paths) {
// Since paths contain each
// path in reverse order,
// so reverse it
Collections.reverse(v);
// Print node for the current path
for ( int u : v)
System.out.print(u + " " );
System.out.println();
}
}
public static void main (String[] args)
{
// Number of vertices
int n = 6 ;
// array of vectors is used
// to store the graph
// in the form of an adjacency list
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
for ( int i = 0 ; i < n; i++){
adj.add( new ArrayList<>());
}
// Given Graph
add_edge(adj, 0 , 1 );
add_edge(adj, 0 , 2 );
add_edge(adj, 1 , 3 );
add_edge(adj, 1 , 4 );
add_edge(adj, 2 , 3 );
add_edge(adj, 3 , 5 );
add_edge(adj, 4 , 5 );
// Given source and destination
int src = 0 ;
int dest = n - 1 ;
// Function Call
print_paths(adj, n, src, dest);
}
} // This code is contributed by ayush123ngp. |
# Python program for the above approach # Function to form edge between # two vertices src and dest from typing import List
from sys import maxsize
from collections import deque
def add_edge(adj: List [ List [ int ]],
src: int , dest: int ) - > None :
adj[src].append(dest)
adj[dest].append(src)
# Function which finds all the paths # and stores it in paths array def find_paths(paths: List [ List [ int ]], path: List [ int ],
parent: List [ List [ int ]], n: int , u: int ) - > None :
# Base Case
if (u = = - 1 ):
paths.append(path.copy())
return
# Loop for all the parents
# of the given vertex
for par in parent[u]:
# Insert the current
# vertex in path
path.append(u)
# Recursive call for its parent
find_paths(paths, path, parent, n, par)
# Remove the current vertex
path.pop()
# Function which performs bfs # from the given source vertex def bfs(adj: List [ List [ int ]],
parent: List [ List [ int ]], n: int ,
start: int ) - > None :
# dist will contain shortest distance
# from start to every other vertex
dist = [maxsize for _ in range (n)]
q = deque()
# Insert source vertex in queue and make
# its parent -1 and distance 0
q.append(start)
parent[start] = [ - 1 ]
dist[start] = 0
# Until Queue is empty
while q:
u = q[ 0 ]
q.popleft()
for v in adj[u]:
if (dist[v] > dist[u] + 1 ):
# A shorter distance is found
# So erase all the previous parents
# and insert new parent u in parent[v]
dist[v] = dist[u] + 1
q.append(v)
parent[v].clear()
parent[v].append(u)
elif (dist[v] = = dist[u] + 1 ):
# Another candidate parent for
# shortes path found
parent[v].append(u)
# Function which prints all the paths # from start to end def print_paths(adj: List [ List [ int ]], n: int ,
start: int , end: int ) - > None :
paths = []
path = []
parent = [[] for _ in range (n)]
# Function call to bfs
bfs(adj, parent, n, start)
# Function call to find_paths
find_paths(paths, path, parent, n, end)
for v in paths:
# Since paths contain each
# path in reverse order,
# so reverse it
v = reversed (v)
# Print node for the current path
for u in v:
print (u, end = " " )
print ()
# Driver Code if __name__ = = "__main__" :
# Number of vertices
n = 6
# array of vectors is used
# to store the graph
# in the form of an adjacency list
adj = [[] for _ in range (n)]
# Given Graph
add_edge(adj, 0 , 1 )
add_edge(adj, 0 , 2 )
add_edge(adj, 1 , 3 )
add_edge(adj, 1 , 4 )
add_edge(adj, 2 , 3 )
add_edge(adj, 3 , 5 )
add_edge(adj, 4 , 5 )
# Given source and destination
src = 0
dest = n - 1
# Function Call
print_paths(adj, n, src, dest)
# This code is contributed by sanjeev2552 |
/*package whatever //do not write package name here */ using System;
using System.Collections.Generic;
public class GFG
{ // Function to form edge between
// two vertices src and dest
static void add_edge(List<List< int >> adj, int src, int dest){
adj[src].Add(dest);
adj[dest].Add(src);
}
// Function which finds all the paths
// and stores it in paths array
static void find_paths(List<List< int >> paths, List< int > path,
List<List< int >> parent, int n, int u) {
// Base Case
if (u == -1) {
paths.Add( new List< int >(path));
return ;
}
// Loop for all the parents
// of the given vertex
foreach ( int par in parent[u]) {
// Insert the current
// vertex in path
path.Add(u);
// Recursive call for its parent
find_paths(paths, path, parent, n, par);
// Remove the current vertex
path.RemoveAt(path.Count-1);
}
}
// Function which performs bfs
// from the given source vertex
static void bfs(List<List< int >> adj, List<List< int >> parent,
int n, int start) {
// dist will contain shortest distance
// from start to every other vertex
int [] dist = new int [n];
for ( int i=0;i<n;i++)
dist[i] = int .MaxValue;
Queue< int > q = new Queue< int >();
// Insert source vertex in queue and make
// its parent -1 and distance 0
q.Enqueue(start);
parent[start].Clear();
parent[start].Add(-1);
dist[start] = 0;
// Until Queue is empty
while (q.Count!=0) {
int u = q.Dequeue();
foreach ( int v in adj[u]) {
if (dist[v] > dist[u] + 1) {
// A shorter distance is found
// So erase all the previous parents
// and insert new parent u in parent[v]
dist[v] = dist[u] + 1;
q.Enqueue(v);
parent[v].Clear();
parent[v].Add(u);
}
else if (dist[v] == dist[u] + 1) {
// Another candidate parent for
// shortes path found
parent[v].Add(u);
}
}
}
}
// Function which prints all the paths
// from start to end
static void print_paths(List<List< int >> adj, int n, int start, int end){
List<List< int >> paths = new List<List< int >>();
List< int > path = new List< int >();
List<List< int >> parent = new List<List< int >>();
for ( int i = 0; i < n; i++){
parent.Add( new List< int >());
}
// Function call to bfs
bfs(adj, parent, n, start);
// Function call to find_paths
find_paths(paths, path, parent, n, end);
foreach (List< int > v in paths) {
// Since paths contain each
// path in reverse order,
// so reverse it
v.Reverse();
// Print node for the current path
foreach ( int u in v)
Console.Write(u + " " );
Console.WriteLine();
}
}
public static void Main(String[] args)
{
// Number of vertices
int n = 6;
// array of vectors is used
// to store the graph
// in the form of an adjacency list
List<List< int >> adj = new List<List< int >>();
for ( int i = 0; i < n; i++){
adj.Add( new List< int >());
}
// Given Graph
add_edge(adj, 0, 1);
add_edge(adj, 0, 2);
add_edge(adj, 1, 3);
add_edge(adj, 1, 4);
add_edge(adj, 2, 3);
add_edge(adj, 3, 5);
add_edge(adj, 4, 5);
// Given source and destination
int src = 0;
int dest = n - 1;
// Function Call
print_paths(adj, n, src, dest);
}
} // This code is contributed by shikhasingrajput |
// JavaScript program for the above approach class Graph { // Function to form edge between two vertices src and dest
addEdge(adj, src, dest) {
adj[src].push(dest);
adj[dest].push(src);
}
// Function which finds all the paths and stores it in paths array
findPaths(paths, path, parent, n, u) {
// Base Case
if (u === -1) {
paths.push(path.slice());
return ;
}
// Loop for all the parents of the given vertex
for (let i = 0; i < parent[u].length; i++) {
let par = parent[u][i];
// Insert the current vertex in path
path.push(u);
// Recursive call for its parent
this .findPaths(paths, path, parent, n, par);
// Remove the current vertex
path.pop();
}
}
// Function which performs bfs from the given source vertex
bfs(adj, parent, n, start) {
// dist will contain shortest distance from start to every other vertex
let dist = Array(n).fill(Number.MAX_VALUE);
let q = [];
// Insert source vertex in queue and make its parent -1 and distance 0
q.push(start);
parent[start] = [-1];
dist[start] = 0;
// Until Queue is empty
while (q.length > 0) {
let u = q.shift();
for (let i = 0; i < adj[u].length; i++) {
let v = adj[u][i];
if (dist[v] > dist[u] + 1) {
// A shorter distance is found
// So erase all the previous parents
// and insert new parent u in parent[v]
dist[v] = dist[u] + 1;
q.push(v);
parent[v] = [u];
} else if (dist[v] === dist[u] + 1) {
// Another candidate parent for shortes path found
parent[v].push(u);
}
}
}
}
// Function which prints all the paths from start to end
printPaths(adj, n, start, end) {
let paths = [];
let path = [];
let parent = Array(n).fill( null ).map(() => []);
// Function call to bfs
this .bfs(adj, parent, n, start);
// Function call to findPaths
this .findPaths(paths, path, parent, n, end);
for (let i = 0; i < paths.length; i++) {
let v = paths[i];
// Since paths contain each path in reverse order, so reverse it
v.reverse();
// Print node for the current path
console.log(v.join( " " ));
}
}
} let graph = new Graph();
// Number of vertices let n = 6; // Array to store the graph in the form of an adjacency list let adj = []; for (let i = 0; i < n; i++) {
adj.push([]);
} // Given graph graph.addEdge(adj, 0, 1); graph.addEdge(adj, 0, 2); graph.addEdge(adj, 1, 3); graph.addEdge(adj, 1, 4); graph.addEdge(adj, 2, 3); graph.addEdge(adj, 3, 5); graph.addEdge(adj, 4, 5); // Given source and destination let src = 0; let dest = n - 1; // Function call graph.printPaths(adj, n, src, dest); // This code is contributed by lokeshmvs21. |
0 1 3 5 0 2 3 5 0 1 4 5
Time Complexity: O(V + E) where V is the number of vertices and E is the number of edges.
Auxiliary Space: O(V) where V is the number of vertices.