Shortest path in an unweighted graph
Last Updated :
24 May, 2024
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.
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();
Time Complexity: O(V + E), where V is the number of vertices and E is the number of edges.
Auxiliary Space: O(V)
Please Login to comment...