Shortest path in an unweighted graph - GeeksforGeeks

09 Nov, 2021
Given an unweighted graph, a source, and a destination, we need to find the shortest path from source to destination in the graph in the most optimal way. 
unweighted graph of 8 vertices 
Input: source vertex = 0 and destination vertex is = 7.
Output: Shortest path length is:2
        Path is::
        0 3 7

Input: source vertex is = 2 and destination vertex is = 6.
Output: Shortest path length is:5
        Path is::
        2 1 0 3 4 6
One solution is to solve in O(VE) time using Bellman–Ford. If there are no negative weight cycles, then we can solve in O(E + VLogV) time using Dijkstra’s algorithm. Since the graph is unweighted, we can solve this problem in O(V + E) time. The idea is to use a modified version of Breadth-first search in which we keep storing the predecessor of a given vertex while doing the breadth-first search. We first initialize an array dist[0, 1, ...., v-1] such that dist[i] stores the distance of vertex i from the source vertex and array pred[0, 1, ....., v-1] such that pred[i] represents the immediate predecessor of the vertex i in the breadth-first search starting from the source. Now we get the length of the path from source to any other vertex in O(1) time from array d, and for printing the path from source to any vertex we can use array p and that will take O(V) time in worst case as V is the size of array P. So most of the time of the algorithm is spent in doing the Breadth-first search from a given source which we know takes O(V+E) time. Thus the time complexity of our algorithm is O(V+E). Take the following unweighted graph as an example:Following is the complete algorithm for finding the shortest path: 
C++
Java
Python3
C#
// CPP code for printing shortest path between// two vertices of unweighted graph#include <bits/stdc++.h>using namespace std; // utility function to form edge between two vertices// source and destvoid add_edge(vector<int> adj[], int src, int dest){    adj[src].push_back(dest);    adj[dest].push_back(src);} // a modified version of BFS that stores predecessor// of each vertex in array p// and its distance from source in array dbool BFS(vector<int> adj[], int src, int dest, int v,         int pred[], int dist[]){    // a queue to maintain queue of vertices whose    // adjacency list is to be scanned as per normal    // DFS algorithm    list<int> queue;     // boolean array visited[] which stores the    // information whether ith vertex is reached    // at least once in the Breadth first search    bool visited[v];     // initially all vertices are unvisited    // so v[i] for all i is false    // and as no path is yet constructed    // dist[i] for all i set to infinity    for (int i = 0; i < v; i++) {        visited[i] = false;        dist[i] = INT_MAX;        pred[i] = -1;    }     // now source is first to be visited and    // distance from source to itself should be 0    visited[src] = true;    dist[src] = 0;    queue.push_back(src);     // standard BFS algorithm    while (!queue.empty()) {        int u = queue.front();        queue.pop_front();        for (int i = 0; i < adj[u].size(); i++) {            if (visited[adj[u][i]] == false) {                visited[adj[u][i]] = true;                dist[adj[u][i]] = dist[u] + 1;                pred[adj[u][i]] = u;                queue.push_back(adj[u][i]);                 // We stop BFS when we find                // destination.                if (adj[u][i] == dest)                    return true;            }        }    }     return false;} // utility function to print the shortest distance// between source vertex and destination vertexvoid printShortestDistance(vector<int> adj[], int s,                           int dest, int v){    // predecessor[i] array stores predecessor of    // i and distance array stores distance of i    // from s    int pred[v], dist[v];     if (BFS(adj, s, dest, v, pred, dist) == false) {        cout << "Given source and destination"             << " are not connected";        return;    }     // vector path stores the shortest path    vector<int> path;    int crawl = dest;    path.push_back(crawl);    while (pred[crawl] != -1) {        path.push_back(pred[crawl]);        crawl = pred[crawl];    }     // distance from source is in distance array    cout << "Shortest path length is : "         << dist[dest];     // printing path from source to destination    cout << "\nPath is::\n";    for (int i = path.size() - 1; i >= 0; i--)        cout << path[i] << " ";} // Driver program to test above functionsint main(){    // no. of vertices    int v = 8;     // array of vectors is used to store the graph    // in the form of an adjacency list    vector<int> adj[v];     // Creating graph given in the above diagram.    // add_edge function takes adjacency list, source    // and destination vertex as argument and forms    // an edge between them.    add_edge(adj, 0, 1);    add_edge(adj, 0, 3);    add_edge(adj, 1, 2);    add_edge(adj, 3, 4);    add_edge(adj, 3, 7);    add_edge(adj, 4, 5);    add_edge(adj, 4, 6);    add_edge(adj, 4, 7);    add_edge(adj, 5, 6);    add_edge(adj, 6, 7);    int source = 0, dest = 7;    printShortestDistance(adj, source, dest, v);    return 0;}
// Java program to find shortest path in an undirected// graphimport java.util.ArrayList;import java.util.Iterator;import java.util.LinkedList; public class pathUnweighted {     // Driver Program    public static void main(String args[])    {        // No of vertices        int v = 8;         // Adjacency list for storing which vertices are connected        ArrayList<ArrayList<Integer>> adj =                            new ArrayList<ArrayList<Integer>>(v);        for (int i = 0; i < v; i++) {            adj.add(new ArrayList<Integer>());        }         // Creating graph given in the above diagram.        // add_edge function takes adjacency list, source        // and destination vertex as argument and forms        // an edge between them.        addEdge(adj, 0, 1);        addEdge(adj, 0, 3);        addEdge(adj, 1, 2);        addEdge(adj, 3, 4);        addEdge(adj, 3, 7);        addEdge(adj, 4, 5);        addEdge(adj, 4, 6);        addEdge(adj, 4, 7);        addEdge(adj, 5, 6);        addEdge(adj, 6, 7);        int source = 0, dest = 7;        printShortestDistance(adj, source, dest, v);    }     // function to form edge between two vertices    // source and dest    private static void addEdge(ArrayList<ArrayList<Integer>> adj, int i, int j)    {        adj.get(i).add(j);        adj.get(j).add(i);    }     // function to print the shortest distance and path    // between source vertex and destination vertex    private static void printShortestDistance(                     ArrayList<ArrayList<Integer>> adj,                             int s, int dest, int v)    {        // predecessor[i] array stores predecessor of        // i and distance array stores distance of i        // from s        int pred[] = new int[v];        int dist[] = new int[v];         if (BFS(adj, s, dest, v, pred, dist) == false) {            System.out.println("Given source and destination" +                                         "are not connected");            return;        }         // LinkedList to store path        LinkedList<Integer> path = new LinkedList<Integer>();        int crawl = dest;        path.add(crawl);        while (pred[crawl] != -1) {            path.add(pred[crawl]);            crawl = pred[crawl];        }         // Print distance        System.out.println("Shortest path length is: " + dist[dest]);         // Print path        System.out.println("Path is ::");        for (int i = path.size() - 1; i >= 0; i--) {            System.out.print(path.get(i) + " ");        }    }     // a modified version of BFS that stores predecessor    // of each vertex in array pred    // and its distance from source in array dist    private static boolean BFS(ArrayList<ArrayList<Integer>> adj, int src,                                  int dest, int v, int pred[], int dist[])    {        // a queue to maintain queue of vertices whose        // adjacency list is to be scanned as per normal        // BFS algorithm using LinkedList of Integer type        LinkedList<Integer> queue = new LinkedList<Integer>();         // boolean array visited[] which stores the        // information whether ith vertex is reached        // at least once in the Breadth first search        boolean visited[] = new boolean[v];         // initially all vertices are unvisited        // so v[i] for all i is false        // and as no path is yet constructed        // dist[i] for all i set to infinity        for (int i = 0; i < v; i++) {            visited[i] = false;            dist[i] = Integer.MAX_VALUE;            pred[i] = -1;        }         // now source is first to be visited and        // distance from source to itself should be 0        visited[src] = true;        dist[src] = 0;        queue.add(src);         // bfs Algorithm        while (!queue.isEmpty()) {            int u = queue.remove();            for (int i = 0; i < adj.get(u).size(); i++) {                if (visited[adj.get(u).get(i)] == false) {                    visited[adj.get(u).get(i)] = true;                    dist[adj.get(u).get(i)] = dist[u] + 1;                    pred[adj.get(u).get(i)] = u;                    queue.add(adj.get(u).get(i));                     // stopping condition (when we find                    // our destination)                    if (adj.get(u).get(i) == dest)                        return true;                }            }        }        return false;    }}// This code is contributed by Sahil Vaid
# Python3 code for printing shortest path between# two vertices of unweighted graph  # utility function to form edge between two vertices# source and destdef add_edge(adj, src, dest):     adj[src].append(dest);    adj[dest].append(src);  # a modified version of BFS that stores predecessor# of each vertex in array p# and its distance from source in array ddef BFS(adj, src, dest, v, pred, dist):     # a queue to maintain queue of vertices whose    # adjacency list is to be scanned as per normal    # DFS algorithm    queue = []      # boolean array visited[] which stores the    # information whether ith vertex is reached    # at least once in the Breadth first search    visited = [False for i in range(v)];      # initially all vertices are unvisited    # so v[i] for all i is false    # and as no path is yet constructed    # dist[i] for all i set to infinity    for i in range(v):         dist[i] = 1000000        pred[i] = -1;         # now source is first to be visited and    # distance from source to itself should be 0    visited[src] = True;    dist[src] = 0;    queue.append(src);      # standard BFS algorithm    while (len(queue) != 0):        u = queue[0];        queue.pop(0);        for i in range(len(adj[u])):                     if (visited[adj[u][i]] == False):                visited[adj[u][i]] = True;                dist[adj[u][i]] = dist[u] + 1;                pred[adj[u][i]] = u;                queue.append(adj[u][i]);                  # We stop BFS when we find                # destination.                if (adj[u][i] == dest):                    return True;      return False;  # utility function to print the shortest distance# between source vertex and destination vertexdef printShortestDistance(adj, s, dest, v):         # predecessor[i] array stores predecessor of    # i and distance array stores distance of i    # from s    pred=[0 for i in range(v)]    dist=[0 for i in range(v)];      if (BFS(adj, s, dest, v, pred, dist) == False):        print("Given source and destination are not connected")      # vector path stores the shortest path    path = []    crawl = dest;    crawl = dest;    path.append(crawl);         while (pred[crawl] != -1):        path.append(pred[crawl]);        crawl = pred[crawl];           # distance from source is in distance array    print("Shortest path length is : " + str(dist[dest]), end = '')      # printing path from source to destination    print("\nPath is : : ")         for i in range(len(path)-1, -1, -1):        print(path[i], end=' ')         # Driver program to test above functionsif __name__=='__main__':         # no. of vertices    v = 8;      # array of vectors is used to store the graph    # in the form of an adjacency list    adj = [[] for i in range(v)];      # Creating graph given in the above diagram.    # add_edge function takes adjacency list, source    # and destination vertex as argument and forms    # an edge between them.    add_edge(adj, 0, 1);    add_edge(adj, 0, 3);    add_edge(adj, 1, 2);    add_edge(adj, 3, 4);    add_edge(adj, 3, 7);    add_edge(adj, 4, 5);    add_edge(adj, 4, 6);    add_edge(adj, 4, 7);    add_edge(adj, 5, 6);    add_edge(adj, 6, 7);    source = 0    dest = 7;    printShortestDistance(adj, source, dest, v);     # This code is contributed by rutvik_56
// C# program to find shortest// path in an undirected graphusing System;using System.Collections.Generic;class pathUnweighted{ // Driver codepublic static void Main(String []args){  // No of vertices  int v = 8;   // Adjacency list for storing  // which vertices are connected  List<List<int>> adj =            new List<List<int>>(v);     for (int i = 0; i < v; i++)  {    adj.Add(new List<int>());  }   // Creating graph given in the  // above diagram. add_edge  // function takes adjacency list,  // source and destination vertex  // as argument and forms an edge  // between them.  addEdge(adj, 0, 1);  addEdge(adj, 0, 3);  addEdge(adj, 1, 2);  addEdge(adj, 3, 4);  addEdge(adj, 3, 7);  addEdge(adj, 4, 5);  addEdge(adj, 4, 6);  addEdge(adj, 4, 7);  addEdge(adj, 5, 6);  addEdge(adj, 6, 7);  int source = 0, dest = 7;  printShortestDistance(adj, source,                        dest, v);} // function to form edge between// two vertices source and destprivate static void addEdge(List<List<int>> adj,                            int i, int j){  adj[i].Add(j);  adj[j].Add(i);} // function to print the shortest// distance and path between source// vertex and destination vertexprivate static void printShortestDistance(List<List<int>> adj,                                          int s, int dest, int v){  // predecessor[i] array stores  // predecessor of i and distance  // array stores distance of i  // from s  int []pred = new int[v];  int []dist = new int[v];   if (BFS(adj, s, dest,          v, pred, dist) == false)  {    Console.WriteLine("Given source and destination" +                      "are not connected");    return;  }   // List to store path  List<int> path = new List<int>();  int crawl = dest;  path.Add(crawl);     while (pred[crawl] != -1)  {    path.Add(pred[crawl]);    crawl = pred[crawl];  }   // Print distance  Console.WriteLine("Shortest path length is: " +                     dist[dest]);   // Print path  Console.WriteLine("Path is ::");     for (int i = path.Count - 1;           i >= 0; i--)  {    Console.Write(path[i] + " ");  }} // a modified version of BFS that// stores predecessor of each vertex// in array pred and its distance// from source in array distprivate static bool BFS(List<List<int>> adj,                        int src, int dest,                        int v, int []pred,                        int []dist){  // a queue to maintain queue of  // vertices whose adjacency list  // is to be scanned as per normal  // BFS algorithm using List of int type  List<int> queue = new List<int>();   // bool array visited[] which  // stores the information whether  // ith vertex is reached at least  // once in the Breadth first search  bool []visited = new bool[v];   // initially all vertices are  // unvisited so v[i] for all i  // is false and as no path is  // yet constructed dist[i] for  // all i set to infinity  for (int i = 0; i < v; i++)  {    visited[i] = false;    dist[i] = int.MaxValue;    pred[i] = -1;  }   // now source is first to be  // visited and distance from  // source to itself should be 0  visited[src] = true;  dist[src] = 0;  queue.Add(src);   // bfs Algorithm  while (queue.Count != 0)  {    int u = queue[0];    queue.RemoveAt(0);         for (int i = 0;             i < adj[u].Count; i++)    {      if (visited[adj[u][i]] == false)      {        visited[adj[u][i]] = true;        dist[adj[u][i]] = dist[u] + 1;        pred[adj[u][i]] = u;        queue.Add(adj[u][i]);         // stopping condition (when we        // find our destination)        if (adj[u][i] == dest)          return true;      }    }  }  return false;}} // This code is contributed by Rajput-Ji
Shortest path length is : 2
Path is::
0 3 7
 
Time Complexity : O(V + E) Auxiliary Space: O(V) 
svision
Rajput-Ji
rutvik_56
uttamsingh
BFS
cpp-queue
Graph
Graph
BFS
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Ford-Fulkerson Algorithm for Maximum Flow Problem
Traveling Salesman Problem (TSP) Implementation
Check whether a given graph is Bipartite or not
Iterative Depth First Traversal of Graph
m Coloring Problem | Backtracking-5
Kahn's algorithm for Topological Sorting
Best First Search (Informed Search)
Hamiltonian Cycle | Backtracking-6
Longest Path in a Directed Acyclic Graph
Connected Components in an undirected graph