Open In App

Shortest path in an unweighted graph

Last Updated : 24 May, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an unweighted, undirected graph of V nodes and E edges, a source node S, and a destination node D, we need to find the shortest path from node S to node D in the graph.

Shortest-Path-in-an-Unweighted-Graph

Input: V = 8, E = 10, S = 0, D = 7, edges[][] = {{0, 1}, {1, 2}, {0, 3}, {3, 4}, {4, 7}, {3, 7}, {6, 7}, {4, 5}, {4, 6}, {5, 6}}
Output: 0 3 7
Explanation: The shortest path is 0 -> 3 -> 7.

Input: V = 8, E = 10, S = 2, D = 6, edges[][] = {{0, 1}, {1, 2}, {0, 3}, {3, 4}, {4, 7}, {3, 7}, {6, 7}, {4, 5}, {4, 6}, {5, 6}}
Output: 2 1 0 3 4 6
Explanation: The shortest path is 2 -> 1 -> 0 -> 3 – > 4 -> 6.

Approach:

The idea is to use a modified version of Breadth-First Search in which we keep storing the parent 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 par[0, 1, ….., v-1] such that par[i] represents the parent 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 from array dist[], and for printing the path from source to any vertex we can use array par[].

Implementation:

C++
#include <bits/stdc++.h>
using namespace std;

// Modified bfs to store the parent of nodes along with the
// distance from source node
void bfs(vector<vector<int> >& graph, int S,
         vector<int>& par, vector<int>& dist)
{
    // queue to store the nodes in the order they are
    // visited
    queue<int> q;
    // Mark the distance of the source node as 0
    dist[S] = 0;
    // Push the source node to the queue
    q.push(S);

    // Iterate till the queue is not empty
    while (!q.empty()) {
        // Pop the node at the front of the queue
        int node = q.front();
        q.pop();

        // Explore all the neighbours of the current node
        for (int neighbour : graph[node]) {
            // Check if the neighbouring node is not visited
            if (dist[neighbour] == 1e9) {
                // Mark the current node as the parent of
                // the neighbouring node
                par[neighbour] = node;
                // Mark the distance of the neighbouring
                // node as distance of the current node + 1
                dist[neighbour] = dist[node] + 1;
                // Insert the neighbouring node to the queue
                q.push(neighbour);
            }
        }
    }
}

// Function to print the shortest distance between source
// vertex and destination vertex
void printShortestDistance(vector<vector<int> >& graph,
                           int S, int D, int V)
{
    // par[] array stores the parent of nodes
    vector<int> par(V, -1);

    // dist[] array stores distance of nodes from S
    vector<int> dist(V, 1e9);

    // function call to find the distance of all nodes and
    // their parent nodes
    bfs(graph, S, par, dist);

    if (dist[D] == 1e9) {
        cout << "Source and Destination are not connected";
        return;
    }

    // vector path stores the shortest path
    vector<int> path;
    int currentNode = D;
    path.push_back(D);
    while (par[currentNode] != -1) {
        path.push_back(par[currentNode]);
        currentNode = par[currentNode];
    }

    // printing path from source to destination
    for (int i = path.size() - 1; i >= 0; i--)
        cout << path[i] << " ";
}

// Driver program to test above functions
int main()
{
    // no. of vertices
    int V = 8, E = 10;
    // Source and Destination vertex
    int S = 2, D = 6;
    // edge list
    vector<vector<int> > edges
        = { { 0, 1 }, { 1, 2 }, { 0, 3 }, { 3, 4 },
            { 4, 7 }, { 3, 7 }, { 6, 7 }, { 4, 5 },
            { 4, 6 }, { 5, 6 } };

    // vector to store the graph as adjacency list
    vector<vector<int> > graph(V);
    for (auto edge : edges) {
        graph[edge[0]].push_back(edge[1]);
        graph[edge[1]].push_back(edge[0]);
    }

    printShortestDistance(graph, S, D, V);
    return 0;
}
Java
import java.util.*;

public class ShortestPathBFS {
    // Modified bfs to store the parent of nodes along with
    // the distance from the source node
    static void bfs(List<List<Integer> > graph, int S,
                    List<Integer> par, List<Integer> dist)
    {
        // Queue to store the nodes in the order they are
        // visited
        Queue<Integer> q = new LinkedList<>();
        // Mark the distance of the source node as 0
        dist.set(S, 0);
        // Push the source node to the queue
        q.add(S);

        // Iterate until the queue is not empty
        while (!q.isEmpty()) {
            // Pop the node at the front of the queue
            int node = q.poll();

            // Explore all the neighbors of the current node
            for (int neighbor : graph.get(node)) {
                // Check if the neighboring node is not
                // visited
                if (dist.get(neighbor)
                    == Integer.MAX_VALUE) {
                    // Mark the current node as the parent
                    // of the neighboring node
                    par.set(neighbor, node);
                    // Mark the distance of the neighboring
                    // node as the distance of the current
                    // node + 1
                    dist.set(neighbor, dist.get(node) + 1);
                    // Insert the neighboring node to the
                    // queue
                    q.add(neighbor);
                }
            }
        }
    }

    // Function to print the shortest distance between the
    // source vertex and destination vertex
    static void
    printShortestDistance(List<List<Integer> > graph, int S,
                          int D, int V)
    {
        // par[] array stores the parent of nodes
        List<Integer> par
            = new ArrayList<>(Collections.nCopies(V, -1));

        // dist[] array stores the distance of nodes from S
        List<Integer> dist = new ArrayList<>(
            Collections.nCopies(V, Integer.MAX_VALUE));

        // Function call to find the distance of all nodes
        // and their parent nodes
        bfs(graph, S, par, dist);

        if (dist.get(D) == Integer.MAX_VALUE) {
            System.out.println(
                "Source and Destination are not connected");
            return;
        }

        // List path stores the shortest path
        List<Integer> path = new ArrayList<>();
        int currentNode = D;
        path.add(D);
        while (par.get(currentNode) != -1) {
            path.add(par.get(currentNode));
            currentNode = par.get(currentNode);
        }

        // Printing path from source to destination
        for (int i = path.size() - 1; i >= 0; i--)
            System.out.print(path.get(i) + " ");
    }

    // Driver program to test above functions
    public static void main(String[] args)
    {
        // no. of vertices
        int V = 8;
        // Source and Destination vertex
        int S = 2, D = 6;
        // Edge list
        List<List<Integer> > edges = Arrays.asList(
            Arrays.asList(0, 1), Arrays.asList(1, 2),
            Arrays.asList(0, 3), Arrays.asList(3, 4),
            Arrays.asList(4, 7), Arrays.asList(3, 7),
            Arrays.asList(6, 7), Arrays.asList(4, 5),
            Arrays.asList(4, 6), Arrays.asList(5, 6));

        // List to store the graph as an adjacency list
        List<List<Integer> > graph = new ArrayList<>(V);
        for (int i = 0; i < V; i++) {
            graph.add(new ArrayList<>());
        }

        for (List<Integer> edge : edges) {
            graph.get(edge.get(0)).add(edge.get(1));
            graph.get(edge.get(1)).add(edge.get(0));
        }

        printShortestDistance(graph, S, D, V);
    }
}
Python
from collections import deque


def bfs(graph, S, par, dist):
    # Queue to store the nodes in the order they are visited
    q = deque()
    # Mark the distance of the source node as 0
    dist[S] = 0
    # Push the source node to the queue
    q.append(S)

    # Iterate until the queue is not empty
    while q:
        # Pop the node at the front of the queue
        node = q.popleft()

        # Explore all the neighbors of the current node
        for neighbor in graph[node]:
            # Check if the neighboring node is not visited
            if dist[neighbor] == float('inf'):
                # Mark the current node as the parent of the neighboring node
                par[neighbor] = node
                # Mark the distance of the neighboring node as the distance of the current node + 1
                dist[neighbor] = dist[node] + 1
                # Insert the neighboring node to the queue
                q.append(neighbor)


def print_shortest_distance(graph, S, D, V):
    # par[] array stores the parent of nodes
    par = [-1] * V

    # dist[] array stores the distance of nodes from S
    dist = [float('inf')] * V

    # Function call to find the distance of all nodes and their parent nodes
    bfs(graph, S, par, dist)

    if dist[D] == float('inf'):
        print("Source and Destination are not connected")
        return

    # List path stores the shortest path
    path = []
    current_node = D
    path.append(D)
    while par[current_node] != -1:
        path.append(par[current_node])
        current_node = par[current_node]

    # Printing path from source to destination
    for i in range(len(path) - 1, -1, -1):
        print(path[i], end=" ")


# Driver program to test above functions
if __name__ == "__main__":
    # no. of vertices
    V = 8
    # Source and Destination vertex
    S, D = 2, 6
    # Edge list
    edges = [
        [0, 1], [1, 2], [0, 3], [3, 4],
        [4, 7], [3, 7], [6, 7], [4, 5],
        [4, 6], [5, 6]
    ]

    # List to store the graph as an adjacency list
    graph = [[] for _ in range(V)]

    for edge in edges:
        graph[edge[0]].append(edge[1])
        graph[edge[1]].append(edge[0])

    print_shortest_distance(graph, S, D, V)
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
using System.Linq;

public class GFG {
    // Modified BFS to store the parent of nodes along with
    // the distance from the source node
    static void BFS(List<List<int> > graph, int S,
                    List<int> par, List<int> dist)
    {
        // Queue to store the nodes in the order they are
        // visited
        Queue<int> q = new Queue<int>();
        // Mark the distance of the source node as 0
        dist[S] = 0;
        // Push the source node to the queue
        q.Enqueue(S);

        // Iterate until the queue is not empty
        while (q.Count > 0) {
            // Dequeue the node at the front of the queue
            int node = q.Dequeue();

            // Explore all the neighbors of the current node
            foreach(int neighbor in graph[node])
            {
                // Check if the neighboring node is not
                // visited
                if (dist[neighbor] == int.MaxValue) {
                    // Mark the current node as the parent
                    // of the neighboring node
                    par[neighbor] = node;
                    // Mark the distance of the neighboring
                    // node as the distance of the current
                    // node + 1
                    dist[neighbor] = dist[node] + 1;
                    // Insert the neighboring node to the
                    // queue
                    q.Enqueue(neighbor);
                }
            }
        }
    }

    // Function to print the shortest distance between the
    // source vertex and destination vertex
    static void
    PrintShortestDistance(List<List<int> > graph, int S,
                          int D, int V)
    {
        // par[] array stores the parent of nodes
        List<int> par = Enumerable.Repeat(-1, V).ToList();

        // dist[] array stores the distance of nodes from S
        List<int> dist
            = Enumerable.Repeat(int.MaxValue, V).ToList();

        // Function call to find the distance of all nodes
        // and their parent nodes
        BFS(graph, S, par, dist);

        if (dist[D] == int.MaxValue) {
            Console.WriteLine(
                "Source and Destination are not connected");
            return;
        }

        // List path stores the shortest path
        List<int> path = new List<int>();
        int currentNode = D;
        path.Add(D);
        while (par[currentNode] != -1) {
            path.Add(par[currentNode]);
            currentNode = par[currentNode];
        }

        // Printing path from source to destination
        for (int i = path.Count - 1; i >= 0; i--)
            Console.Write(path[i] + " ");
    }

    // Driver program to test above functions
    public static void Main(string[] args)
    {
        // no. of vertices
        int V = 8;
        // Source and Destination vertex
        int S = 2, D = 6;
        // Edge list
        List<List<int> > edges = new List<List<int> >{
            new List<int>{ 0, 1 }, new List<int>{ 1, 2 },
            new List<int>{ 0, 3 }, new List<int>{ 3, 4 },
            new List<int>{ 4, 7 }, new List<int>{ 3, 7 },
            new List<int>{ 6, 7 }, new List<int>{ 4, 5 },
            new List<int>{ 4, 6 }, new List<int>{ 5, 6 }
        };

        // List to store the graph as an adjacency list
        List<List<int> > graph
            = Enumerable.Range(0, V)
                  .Select(_ = > new List<int>())
                  .ToList();

        foreach(List<int> edge in edges)
        {
            graph[edge[0]].Add(edge[1]);
            graph[edge[1]].Add(edge[0]);
        }

        PrintShortestDistance(graph, S, D, V);
    }
}
JavaScript
class ShortestPathBFS {
    static bfs(graph, S, par, dist) {
        const q = [];
        dist[S] = 0;
        q.push(S);

        while (q.length > 0) {
            const node = q.shift();

            for (const neighbor of graph[node]) {
                if (dist[neighbor] === Infinity) {
                    par[neighbor] = node;
                    dist[neighbor] = dist[node] + 1;
                    q.push(neighbor);
                }
            }
        }
    }

    static printShortestDistance(graph, S, D, V) {
        const par = Array(V).fill(-1);
        const dist = Array(V).fill(Infinity);
        ShortestPathBFS.bfs(graph, S, par, dist);

        if (dist[D] === Infinity) {
            console.log("Source and Destination are not connected");
            return;
        }

        const path = [];
        let currentNode = D;
        path.push(D);
        while (par[currentNode] !== -1) {
            path.push(par[currentNode]);
            currentNode = par[currentNode];
        }

        // Concatenate the path elements into a single string
        const pathString = path.reverse().join(" ");
        console.log(pathString);
    }

    static main() {
        // no. of vertices
        const V = 8;
        // Source and Destination vertex
        const S = 2, D = 6;
        // Edge list
        const edges = [
            [0, 1], [1, 2], [0, 3], [3, 4],
            [4, 7], [3, 7], [6, 7], [4, 5],
            [4, 6], [5, 6]
        ];

        // Array to store the graph as an adjacency list
        const graph = Array.from({ length: V }, () => []);

        for (const edge of edges) {
            graph[edge[0]].push(edge[1]);
            graph[edge[1]].push(edge[0]);
        }

        ShortestPathBFS.printShortestDistance(graph, S, D, V);
    }
}

// Run the main function
ShortestPathBFS.main();

Output
2 1 0 3 4 6 

Time Complexity: O(V + E), where V is the number of vertices and E is the number of edges.
Auxiliary Space: O(V)



Previous Article
Next Article

Similar Reads

Difference between the shortest and second shortest path in an Unweighted Bidirectional Graph
Given an unweighted bidirectional graph containing N nodes and M edges represented by an array arr[][2]. The task is to find the difference in length of the shortest and second shortest paths from node 1 to N. If the second shortest path does not exist, print 0. Note: The graph is connected, does not contain multiple edges and self loops. (2&lt;=N
15+ min read
Multi Source Shortest Path in Unweighted Graph
Suppose there are n towns connected by m bidirectional roads. There are s towns among them with a police station. We want to find out the distance of each town from the nearest police station. If the town itself has one the distance is 0. Example: Input : Number of Vertices = 6 Number of Edges = 9 Towns with Police Station : 1, 5 Edges: 1 2 1 6 2 6
15+ min read
Number of shortest paths in an unweighted and directed graph
Given an unweighted directed graph, can be cyclic or acyclic. Print the number of shortest paths from a given vertex to each of the vertices. For example consider the below graph. There is one shortest path vertex 0 to vertex 0 (from each vertex there is a single shortest path to itself), one shortest path between vertex 0 to vertex 2 (0-&gt;2), an
11 min read
Shortest cycle in an undirected unweighted graph
Given an undirected unweighted graph. The task is to find the length of the shortest cycle in the given graph. If no cycle exists print -1. Examples: Input: Output: 4 Cycle 6 -&gt; 1 -&gt; 5 -&gt; 0 -&gt; 6 Input: Output: 3 Cycle 6 -&gt; 1 -&gt; 2 -&gt; 6 Prerequisites: Dijkstra Approach: For every vertex, we check if it is possible to get the shor
8 min read
Time saved travelling in shortest route and shortest path through given city
Given a matrix mat[][] of size N * N, where mat[i][j] represents the time taken to reach from ith city to jth city. Also, given M queries in the form of three arrays S[], I[], and D[] representing source, intermediate, and destination respectively. The task is to find the time taken to go from S[i] to D[i] using I[i] city and the time that can be s
10 min read
Find any simple cycle in an undirected unweighted Graph
Given an un-directed and unweighted connected graph, find a simple cycle in that graph (if it exists). Simple Cycle: A simple cycle is a cycle in a Graph with no repeated vertices (except for the beginning and ending vertex). Basically, if a cycle can't be broken down to two or more cycles, then it is a simple cycle. For better understanding, refer
13 min read
Applications, Advantages and Disadvantages of Unweighted Graph
An unweighted graph is a graph in which the edges do not have weights or costs associated with them. Instead, they simply represent the presence of a connection between two vertices. In this article we will explore the simplicity of unweighted graphs, where connections between vertices are represented without the complexity of edge weights. From so
3 min read
Graph implementation using STL for competitive programming | Set 1 (DFS of Unweighted and Undirected)
We have introduced Graph basics in Graph and its representations. In this post, a different STL-based representation is used that can be helpful to quickly implement graphs using vectors. The implementation is for the adjacency list representation of the graph. Following is an example undirected and unweighted graph with 5 vertices. Below is an adj
7 min read
Shortest path from source to destination such that edge weights along path are alternatively increasing and decreasing
Given a connected graph with N vertices and M edges. The task is to find the shortest path from source to the destination vertex such that the difference between adjacent edge weights in the shortest path change from positive to negative and vice versa ( Weight(E1) &gt; Weight(E2) &lt; Weight(E3) .... ). If no such path exists then print -1. Exampl
13 min read
Shortest path with exactly k edges in a directed and weighted graph
Given a directed and two vertices ‘u’ and ‘v’ in it, find shortest path from ‘u’ to ‘v’ with exactly k edges on the path. The graph is given as adjacency matrix representation where value of graph[i][j] indicates the weight of an edge from vertex i to vertex j and a value INF(infinite) indicates no edge from i to j. For example, consider the follow
15+ min read
Article Tags :
Practice Tags :