Print all shortest paths between given source and destination in an undirected graph - GeeksforGeeks

03 Feb, 2022
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 -> 50 -> 2 -> 3 -> 50 -> 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.
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: 
cpp14
Java
Python3
C#
// Cpp program for the above approach#include <bits/stdc++.h>using namespace std; // Function to form edge between// two vertices src and destvoid 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 arrayvoid 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 vertexvoid 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 endvoid 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 Codeint 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 destfrom typing import Listfrom sys import maxsizefrom 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 arraydef 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 vertexdef 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 enddef 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 Codeif __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
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. 
sanjeev2552
ayush123ngp
gulshankumarar231
clintra
shikhasingrajput
BFS
Data Structures
Graph Traversals
Algorithms
Competitive Programming
Data Structures
Graph
Data Structures
Graph
BFS
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
SDE SHEET - A Complete Guide for SDE Preparation
DSA Sheet by Love Babbar
Introduction to Algorithms
Difference between Informed and Uninformed Search in AI
How to write a Pseudo Code?
Practice for cracking any coding interview
Arrow operator -> in C/C++ with Examples
Competitive Programming - A Complete Guide
Modulo 10^9+7 (1000000007)
Prefix Sum Array - Implementation and Applications in Competitive Programming