Open In App

Shortest path in a directed graph by Dijkstra’s algorithm

Improve
Improve
Like Article
Like
Save
Share
Report

Given a directed graph and a source vertex in the graph, the task is to find the shortest distance and path from source to target vertex in the given graph where edges are weighted (non-negative) and directed from parent vertex to source vertices.

Approach: 

  • Mark all vertices unvisited. Create a set of all unvisited vertices.
  • Assign zero distance value to source vertex and infinity distance value to all other vertices.
  • Set the source vertex as current vertex
  • For current vertex, consider all of its unvisited children and calculate their tentative distances through the current. (distance of current + weight of the corresponding edge) Compare the newly calculated distance to the current assigned value (can be infinity for some vertices) and assign the smaller one.
  • After considering all the unvisited children of the current vertex, mark the current as visited and remove it from the unvisited set.
  • Similarly, continue for all the vertex until all the nodes are visited.

Below is the implementation of the above approach:

C++




// C++ implementation to find the
// shortest path in a directed
// graph from source vertex to
// the destination vertex
 
#include <bits/stdc++.h>
#define infi 1000000000
using namespace std;
 
// Class of the node
class Node {
public:
    int vertexNumber;
 
    // Adjacency list that shows the
    // vertexNumber of child vertex
    // and the weight of the edge
    vector<pair<int, int> > children;
    Node(int vertexNumber)
    {
        this->vertexNumber = vertexNumber;
    }
 
    // Function to add the child for
    // the given node
    void add_child(int vNumber, int length)
    {
        pair<int, int> p;
        p.first = vNumber;
        p.second = length;
        children.push_back(p);
    }
};
 
// Function to find the distance of
// the node from the given source
// vertex to the destination vertex
vector<int> dijkstraDist(
    vector<Node*> g,
    int s, vector<int>& path)
{
    // Stores distance of each
    // vertex from source vertex
    vector<int> dist(g.size());
 
    // Boolean array that shows
    // whether the vertex 'i'
    // is visited or not
    bool visited[g.size()];
    for (int i = 0; i < g.size(); i++) {
        visited[i] = false;
        path[i] = -1;
        dist[i] = infi;
    }
    dist[s] = 0;
    path[s] = -1;
    int current = s;
 
    // Set of vertices that has
    // a parent (one or more)
    // marked as visited
    unordered_set<int> sett;
    while (true) {
 
        // Mark current as visited
        visited[current] = true;
        for (int i = 0;
             i < g[current]->children.size();
             i++) {
            int v = g[current]->children[i].first;
            if (visited[v])
                continue;
 
            // Inserting into the
            // visited vertex
            sett.insert(v);
            int alt
                = dist[current]
                  + g[current]->children[i].second;
 
            // Condition to check the distance
            // is correct and update it
            // if it is minimum from the previous
            // computed distance
            if (alt < dist[v]) {
                dist[v] = alt;
                path[v] = current;
            }
        }
        sett.erase(current);
        if (sett.empty())
            break;
 
        // The new current
        int minDist = infi;
        int index = 0;
 
        // Loop to update the distance
        // of the vertices of the graph
        for (int a: sett) {
            if (dist[a] < minDist) {
                minDist = dist[a];
                index = a;
            }
        }
        current = index;
    }
    return dist;
}
 
// Function to print the path
// from the source vertex to
// the destination vertex
void printPath(vector<int> path,
               int i, int s)
{
    if (i != s) {
 
        // Condition to check if
        // there is no path between
        // the vertices
        if (path[i] == -1) {
            cout << "Path not found!!";
            return;
        }
        printPath(path, path[i], s);
        cout << path[i] << " ";
    }
}
 
// Driver Code
int main()
{
    vector<Node*> v;
    int n = 4, s = 0, e = 5;
 
    // Loop to create the nodes
    for (int i = 0; i < n; i++) {
        Node* a = new Node(i);
        v.push_back(a);
    }
 
    // Creating directed
    // weighted edges
    v[0]->add_child(1, 1);
    v[0]->add_child(2, 4);
    v[1]->add_child(2, 2);
    v[1]->add_child(3, 6);
    v[2]->add_child(3, 3);
 
    vector<int> path(v.size());
    vector<int> dist
        = dijkstraDist(v, s, path);
 
    // Loop to print the distance of
    // every node from source vertex
    for (int i = 0; i < dist.size(); i++) {
        if (dist[i] == infi) {
            cout << i << " and " << s
                 << " are not connected"
                 << endl;
            continue;
        }
        cout << "Distance of " << i
             << "th vertex from source vertex "
             << s << " is: "
             << dist[i] << endl;
    }
    return 0;
}


Java




// Java implementation to find the
// shortest path in a directed
// graph from source vertex to
// the destination vertex
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
class Pair {
    int first, second;
 
    public Pair(int first, int second)
    {
        this.first = first;
        this.second = second;
    }
}
 
public class GFG {
 
    static final int infi = 1000000000;
 
    // Class of the node
    static class Node {
        int vertexNumber;
 
        // Adjacency list that shows the
        // vertexNumber of child vertex
        // and the weight of the edge
        List<Pair> children;
 
        Node(int vertexNumber)
        {
            this.vertexNumber = vertexNumber;
            children = new ArrayList<>();
        }
 
        // Function to add the child for
        // the given node
        void add_child(int vNumber, int length)
        {
            Pair p = new Pair(vNumber, length);
            children.add(p);
        }
    }
 
    // Function to find the distance of
    // the node from the given source
    // vertex to the destination vertex
    static int[] dijkstraDist(List<Node> g, int s,
                              int[] path)
    {
 
        // Stores distance of each
        // vertex from source vertex
        int[] dist = new int[g.size()];
 
        // Boolean array that shows
        // whether the vertex 'i'
        // is visited or not
        boolean[] visited = new boolean[g.size()];
        for (int i = 0; i < g.size(); i++) {
            visited[i] = false;
            path[i] = -1;
            dist[i] = infi;
        }
        dist[s] = 0;
        path[s] = -1;
        int current = s;
 
        // Set of vertices that has
        // a parent (one or more)
        // marked as visited
        Set<Integer> sett = new HashSet<>();
        while (true) {
 
            // Mark current as visited
            visited[current] = true;
            for (int i = 0;
                 i < g.get(current).children.size(); i++) {
                int v
                    = g.get(current).children.get(i).first;
 
                if (visited[v])
                    continue;
 
                // Inserting into the
                // visited vertex
                sett.add(v);
                int alt = dist[current]
                          + g.get(current)
                                .children.get(i)
                                .second;
 
                // Condition to check the distance
                // is correct and update it
                // if it is minimum from the previous
                // computed distance
                if (alt < dist[v]) {
                    dist[v] = alt;
                    path[v] = current;
                }
            }
            sett.remove(current);
 
            if (sett.isEmpty())
                break;
 
            // The new current
            int minDist = infi;
            int index = 0;
 
            // Loop to update the distance
            // of the vertices of the graph
            for (int a : sett) {
                if (dist[a] < minDist) {
                    minDist = dist[a];
                    index = a;
                }
            }
            current = index;
        }
        return dist;
    }
 
    // Function to print the path
    // from the source vertex to
    // the destination vertex
    void printPath(int[] path, int i, int s)
    {
        if (i != s) {
 
            // Condition to check if
            // there is no path between
            // the vertices
            if (path[i] == -1) {
                System.out.println("Path not found!!");
                return;
            }
            printPath(path, path[i], s);
            System.out.print(path[i] + " ");
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        List<Node> v = new ArrayList<>();
        int n = 4, s = 0, e = 5;
 
        // Loop to create the nodes
        for (int i = 0; i < n; i++) {
            Node a = new Node(i);
            v.add(a);
        }
 
        // Creating directed
        // weighted edges
        v.get(0).add_child(1, 1);
        v.get(0).add_child(2, 4);
        v.get(1).add_child(2, 2);
        v.get(1).add_child(3, 6);
        v.get(2).add_child(3, 3);
 
        int[] path = new int[v.size()];
        int[] dist = dijkstraDist(v, s, path);
 
        // Loop to print the distance of
        // every node from source vertex
        for (int i = 0; i < dist.length; i++) {
            if (dist[i] == infi) {
                System.out.printf("%d and %d are not "
                                      + "connected\n",
                                  i, s);
                continue;
            }
            System.out.printf(
                "Distance of %dth vertex "
                    + "from source vertex %d is: %d\n",
                i, s, dist[i]);
        }
    }
}
 
// This code is contributed by sanjeev2552


Python3




# Python3 implementation to find the
# shortest path in a directed
# graph from source vertex to
# the destination vertex
class Pair:
    def __init__(self, first, second):
        self.first = first
        self.second = second
infi = 1000000000;
   
# Class of the node
class Node:
   
    # Adjacency list that shows the
    # vertexNumber of child vertex
    # and the weight of the edge   
    def __init__(self, vertexNumber):       
        self.vertexNumber = vertexNumber
        self.children = []
   
    # Function to add the child for
    # the given node
    def Add_child(self, vNumber, length):   
        p = Pair(vNumber, length);
        self.children.append(p);
       
# Function to find the distance of
# the node from the given source
# vertex to the destination vertex
def dijkstraDist(g, s, path):
       
    # Stores distance of each
    # vertex from source vertex
    dist = [infi for i in range(len(g))]
   
    # bool array that shows
    # whether the vertex 'i'
    # is visited or not
    visited = [False for i in range(len(g))]
     
    for i in range(len(g)):       
        path[i] = -1
    dist[s] = 0;
    path[s] = -1;
    current = s;
   
    # Set of vertices that has
    # a parent (one or more)
    # marked as visited
    sett = set()    
    while (True):
           
        # Mark current as visited
        visited[current] = True;
        for i in range(len(g[current].children)): 
            v = g[current].children[i].first;           
            if (visited[v]):
                continue;
   
            # Inserting into the
            # visited vertex
            sett.add(v);
            alt = dist[current] + g[current].children[i].second;
   
            # Condition to check the distance
            # is correct and update it
            # if it is minimum from the previous
            # computed distance
            if (alt < dist[v]):      
                dist[v] = alt;
                path[v] = current;       
        if current in sett:           
            sett.remove(current);       
        if (len(sett) == 0):
            break;
   
        # The new current
        minDist = infi;
        index = 0;
   
        # Loop to update the distance
        # of the vertices of the graph
        for a in sett:       
            if (dist[a] < minDist):          
                minDist = dist[a];
                index = a;          
        current = index;  
    return dist;
   
# Function to print the path
# from the source vertex to
# the destination vertex
def printPath(path, i, s):
    if (i != s):
           
        # Condition to check if
        # there is no path between
        # the vertices
        if (path[i] == -1):       
            print("Path not found!!");
            return;       
        printPath(path, path[i], s);
        print(path[i] + " ");
      
# Driver Code
if __name__=='__main__':
     
    v = []
    n = 4
    s = 0;
   
    # Loop to create the nodes
    for i in range(n):
        a = Node(i);
        v.append(a);
   
    # Creating directed
    # weighted edges
    v[0].Add_child(1, 1);
    v[0].Add_child(2, 4);
    v[1].Add_child(2, 2);
    v[1].Add_child(3, 6);
    v[2].Add_child(3, 3);
    path = [0 for i in range(len(v))];
    dist = dijkstraDist(v, s, path);
   
    # Loop to print the distance of
    # every node from source vertex
    for i in range(len(dist)):
        if (dist[i] == infi):
         
            print("{0} and {1} are not " +
                              "connected".format(i, s));
            continue;       
        print("Distance of {}th vertex from source vertex {} is: {}".format(
                          i, s, dist[i]));
     
    # This code is contributed by pratham76


C#




// C# implementation to find the
// shortest path in a directed
// graph from source vertex to
// the destination vertex
using System;
using System.Collections;
using System.Collections.Generic;
  
class Pair
{
    public int first, second;
  
    public Pair(int first, int second)
    {
        this.first = first;
        this.second = second;
    }
}
  
class GFG
{
  
static int infi = 1000000000;
  
// Class of the node
class Node
{
    public int vertexNumber;
  
    // Adjacency list that shows the
    // vertexNumber of child vertex
    // and the weight of the edge
    public List<Pair> children;
  
    public Node(int vertexNumber)
    {
        this.vertexNumber = vertexNumber;
        children = new List<Pair>();
    }
  
    // Function to Add the child for
    // the given node
    public void Add_child(int vNumber, int length)
    {
        Pair p = new Pair(vNumber, length);
        children.Add(p);
    }
}
  
// Function to find the distance of
// the node from the given source
// vertex to the destination vertex
static int[] dijkstraDist(List<Node> g,
                          int s, int[] path)
{
      
    // Stores distance of each
    // vertex from source vertex
    int[] dist = new int[g.Count];
  
    // bool array that shows
    // whether the vertex 'i'
    // is visited or not
    bool[] visited = new bool[g.Count];
    for(int i = 0; i < g.Count; i++)
    {
        visited[i] = false;
        path[i] = -1;
        dist[i] = infi;
    }
    dist[s] = 0;
    path[s] = -1;
    int current = s;
  
    // Set of vertices that has
    // a parent (one or more)
    // marked as visited
    HashSet<int> sett = new HashSet<int>();
     
    while (true)
    {
          
        // Mark current as visited
        visited[current] = true;
        for(int i = 0;
                i < g[current].children.Count;
                i++)
        {
            int v = g[current].children[i].first;           
            if (visited[v])
                continue;
  
            // Inserting into the
            // visited vertex
            sett.Add(v);
            int alt = dist[current] +
                     g[current].children[i].second;
  
            // Condition to check the distance
            // is correct and update it
            // if it is minimum from the previous
            // computed distance
            if (alt < dist[v])
            {
                dist[v] = alt;
                path[v] = current;
            }
        }
        sett.Remove(current);
          
        if (sett.Count == 0)
            break;
  
        // The new current
        int minDist = infi;
        int index = 0;
  
        // Loop to update the distance
        // of the vertices of the graph
        foreach(int a in sett)
        {
            if (dist[a] < minDist)
            {
                minDist = dist[a];
                index = a;
            }
        }
        current = index;
    }
    return dist;
}
  
// Function to print the path
// from the source vertex to
// the destination vertex
void printPath(int[] path, int i, int s)
{
    if (i != s)
    {
          
        // Condition to check if
        // there is no path between
        // the vertices
        if (path[i] == -1)
        {
            Console.WriteLine("Path not found!!");
            return;
        }
        printPath(path, path[i], s);
        Console.WriteLine(path[i] + " ");
    }
}
  
// Driver Code
public static void Main(string[] args)
{
    List<Node> v = new List<Node>();
    int n = 4, s = 0;
  
    // Loop to create the nodes
    for(int i = 0; i < n; i++)
    {
        Node a = new Node(i);
        v.Add(a);
    }
  
    // Creating directed
    // weighted edges
    v[0].Add_child(1, 1);
    v[0].Add_child(2, 4);
    v[1].Add_child(2, 2);
    v[1].Add_child(3, 6);
    v[2].Add_child(3, 3);
  
    int[] path = new int[v.Count];
    int[] dist = dijkstraDist(v, s, path);
  
    // Loop to print the distance of
    // every node from source vertex
    for(int i = 0; i < dist.Length; i++)
    {
        if (dist[i] == infi)
        {
            Console.Write("{0} and {1} are not " +
                              "connected\n", i, s);
            continue;
        }
        Console.Write("Distance of {0}th vertex " +
                          "from source vertex {1} is: {2}\n",
                          i, s, dist[i]);
    }
}
}
 
// This code is contributed by rutvik_56


Javascript




// JavaScript implementation to find the
// shortest path in a directed
// graph from source vertex to
// the destination vertex
 
class Pair {
  constructor(first, second) {
    this.first = first;
    this.second = second;
  }
}
 
const infi = 1000000000;
 
// Class of the node
class Node {
  // Adjacency list that shows the
  // vertexNumber of child vertex
  // and the weight of the edge
  constructor(vertexNumber) {
    this.vertexNumber = vertexNumber;
    this.children = [];
  }
 
  // Function to add the child for
  // the given node
  Add_child(vNumber, length) {
    const p = new Pair(vNumber, length);
    this.children.push(p);
  }
}
 
// Function to find the distance of
// the node from the given source
// vertex to the destination vertex
function dijkstraDist(g, s, path) {
  // Stores distance of each
  // vertex from source vertex
  const dist = new Array(g.length).fill(infi);
 
  // bool array that shows
  // whether the vertex 'i'
  // is visited or not
  const visited = new Array(g.length).fill(false);
 
  for (let i = 0; i < g.length; i++) {
    path[i] = -1;
  }
  dist[s] = 0;
  path[s] = -1;
  let current = s;
 
  // Set of vertices that has
  // a parent (one or more)
  // marked as visited
  const sett = new Set();
  while (true) {
    // Mark current as visited
    visited[current] = true;
    for (let i = 0; i < g[current].children.length; i++) {
      const v = g[current].children[i].first;
      if (visited[v]) {
        continue;
      }
 
      // Inserting into the
      // visited vertex
      sett.add(v);
      const alt = dist[current] + g[current].children[i].second;
 
      // Condition to check the distance
      // is correct and update it
      // if it is minimum from the previous
      // computed distance
      if (alt < dist[v]) {
        dist[v] = alt;
        path[v] = current;
      }
    }
    if (sett.has(current)) {
      sett.delete(current);
    }
    if (sett.size === 0) {
      break;
    }
 
    // The new current
    let minDist = infi;
    let index = 0;
 
    // Loop to update the distance
    // of the vertices of the graph
    for (const a of sett) {
      if (dist[a] < minDist) {
        minDist = dist[a];
        index = a;
      }
    }
    current = index;
  }
  return dist;
}
 
 
// Function to print the path
// from the source vertex to
// the destination vertex
function printPath(path, i, s) {
  if (i !== s) {
    // Condition to check if
//there is no path between
// the vertices
if (path[i] === -1) {
console.log("Path not found!!");
return;
}
printPath(path, path[i], s);
console.log(path[i] + " ");
}
}
 
// Driver Code
 
let v = [];
let n = 4;
let s = 0;
let e = 5;
 
// Loop to create the nodes
for (let i = 0; i < n; i++) {
let a = {
vertexNumber: i,
children: []
};
v.push(a);
}
 
// Creating directed
// weighted edges
v[0].children.push({first: 1, second: 1});
v[0].children.push({first: 2, second: 4});
v[1].children.push({first: 2, second: 2});
v[1].children.push({first: 3, second: 6});
v[2].children.push({first: 3, second: 3});
let path = Array(v.length).fill(-1);
let dist = dijkstraDist(v, s, path);
 
// Loop to print the distance of
// every node from source vertex
for (let i = 0; i < dist.length; i++) {
if (dist[i] === infi) {
document.write(i + " and " + s + " are not connected");
continue;
}
document.write("Distance of " + i + "th vertex from source vertex " +
s + " is: " + dist[i]);
}


Output

Distance of 0th vertex from source vertex 0 is: 0
Distance of 1th vertex from source vertex 0 is: 1
Distance of 2th vertex from source vertex 0 is: 3
Distance of 3th vertex from source vertex 0 is: 6

Time Complexity: O((E+V)*logV))
Auxiliary Space: O(V + E)
Related articles: We have already discussed the shortest path in directed graph using Topological Sorting, in this article: Shortest path in Directed Acyclic graph
 



Last Updated : 27 Dec, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads