Shortest path in an unweighted graph (original) (raw)

Last Updated : 11 Jul, 2025

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: 21 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 >& graph, int S, vector& par, vector& dist) { // queue to store the nodes in the order they are // visited queue 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 >& graph, int S, int D, int V) { // par[] array stores the parent of nodes vector 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 > 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 > graph, int S, List par, List dist) { // Queue to store the nodes in the order they are // visited Queue 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 > graph, int S, List par, List dist) { // Queue to store the nodes in the order they are // visited Queue q = new Queue(); // 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();

`

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