×

C++ Dijkstra Algorithm Using the Priority Queue

In this article we will be finding the shortest routes from a source vertex in a graph to all vertices in the graph, given a graph and a source vertex in the graph:

// Program to find Dijkstra's shortest path using
// priority_queue in STL
#include < bits/stdc++.h >
#incliude < stdlib>
using namespace std ;
# define INF 0x3f3f3f3f


// iPair ==> Integer Pair
typedef pair < int , int > iPair ;


// This class represents a directed graph using
// adjacency list representation
class Graph
{
	int V ; // No. of vertices


	// In a weighted graph, we need to store vertex
	// and weight pair for every edge
	list < pair < int , int > > * adj ;


public :
	Graph ( int V ) ; // Creating Constructor of class Graph


	// Add an edge to a graph with this function
	void addedge ( int u , int v , int w ) ;


	// calculating the shortest route from s
	void shortestPath ( int s ) ;
} ;


// Memory is allocated for the adjacency list.
Graph : : Graph (int V )
{
	this -> V = V ;
	adj = new list < iPair > [ V ] ;
}


void Graph : : addedge ( int u , int v , int w )
{
	adj [ u ] . push_back ( make_pair ( v , w ) ) ;
	adj [ v ] . push_back ( make_pair ( u , w ) ) ;
}


// The shortest routes from src to all other vertices are printed. 
void Graph : : shortestPath ( int src )
{
	// Make a priority queue for storing vertices that
	// are being preprocessed
	priority_queue < iPair , vector < iPair > , greater < iPair > > pq ;


	//  Create a distance vector and initialise it.
	// distances as infinite ( INF )
	vector < int > dist ( V , INF ) ;


	// Insert source itself in priority queue and initialize
	// its distance as 0.
	pq.push ( make_pair ( 0 , src ) ) ;
	dist [ src ] = 0 ;


	/* Looping till priority queue becomes empty (or all
	distances are not finalized) */
	while ( !pq.empty ( ) )
	{
		// The first vertex in pair is the minimum distance
		// vertex, extract it from priority queue.
		// vertex label is stored in second of pair (it
		// has to be done this way to keep the vertices
		// sorted distance (distance must be first item
		// in pair)
		int u = pq.top ( ) . second ;
		pq.pop ( ) ;


		// 'i' is used to get all adjacent vertices of a vertex
		list < pair < int , int > > : : iterator i ;
		for ( i = adj [ u ] . begin ( ) ; i != adj [ u ] . end ( ) ; ++i )
		{
			// Get vertex label and weight of current adjacent
			// of u.
			int v = ( * i ) . first ;
			int weight = ( * i ) . second ;


			// If there is a shorter way to v through u.
			if ( dist [ v ] > dist [ u ] + weight )
			{
				// Updating distance of v
				dist [ v ] = dist [ u ] + weight ;
				pq.push ( make_pair ( dist [ v ] , v ) ) ;
			}
		}
	}


	// Print the shortest distances in dist [ ]
	printf ( "Vertex Distance from Source\n" ) ;
	for ( int i = 0 ; i < V ; ++i )
		printf ( "%d \ t \ t %d \n" , i , dist [ i ] ) ;
}
// Test methods of graph class with a driver application.
int main ( )
{
	// Create the graph shown in the figure above.
	int V = 9 ;
	Graph g ( V ) ;


	// making above shown graph
	g.addedge ( 0 , 1 , 4 ) ;
	g.addedge ( 0 , 7 , 8 ) ;
	g.addedge ( 1 , 2 , 8 ) ;
	g.addedge ( 1 , 7 , 11 ) ;
	g.addedge ( 2 , 3 , 7 ) ;
	g.addedge ( 2 , 8 , 2 ) ;
	g.addedge ( 2 , 5 , 4 ) ;
	g.addedge ( 3 , 4 , 9 ) ;
	g.addedge ( 3 , 5 , 14 ) ;
	g.addedge ( 4 , 5 , 10 ) ;
	g.addedge ( 5 , 6 , 2 ) ;
	g.addedge ( 6 , 7 , 1 ) ;
	g.addedge ( 6 , 8 , 6 ) ;
	g.addedge ( 7 , 8 , 7 ) ;


	g.shortestPath ( 0 ) ;


	return 0 ;
}

OUTPUT:

Vertex   Distance from Source
0          0
1          4
2          12
3          19
4          21
5          11
6          9
7          8
8          14
……………………………………………
Process executed in 0.31 seconds
Press any key to continue

Explanation:

  • The second version is simpler in terms of temporal complexity, but it is quite sophisticated since we have created our own priority queue. Because it employs STL, the third implementation is the simplest.
  • The problem with the third method is that it use set, which employs Self-Balancing Binary Search Trees.
  • The heap (or priority queue) is always suggested for Dijkstra's method since the needed actions (extract minimum and reduce key) fit the heap's expertise (or priority queue). The issue is that the decrease key is not supported by the priority queue.
  • To fix the problem, don't update the key; instead, make a new duplicate of it. As a result, several occurrences of the same vertex are allowed in the priority queue.
  • This method does not necessitate a reduction in critical operations and has the following important qualities.

Another method is to express weighted graphs as vectors.

#include < bits/stdc++.h >
#include < isotream >
#include < stdlib >
using namespace std ;
# define INF 0x3f3f3f3f


// iPair ==> Integer Pair
typedef pair < int , int > iPair ; 
// To add an edge
void addedge ( vector < pair < int , int > > adj [ ] , int u , int v , int wt )
{
	adj [ u ] . push_back ( make_pair ( v , wt ) ) ;
	adj [ v ] . push_back ( make_pair ( u , wt ) ) ;
}
// The shortest routes from src to all other vertices are printed.
void shortestPath (vector < pair < int , int > > adj [ ] , int V , int src )
{
	priority_queue< iPair, vector <iPair> , greater<iPair> > pq; 
	// Create a vector for distances and initialize all
	// distances as infinite (INF)
	vector < int > dist ( V , INF ) ; 
	// Insert source itself in priority queue and initialize
	// its distance as 0.
	pq.push ( make_pair ( 0 , src ) ) ;
	dist [ src ] = 0 ; 
	/* Looping till priority queue becomes empty (or all
	distances are not finalized) */
	while ( ! pq.empty ( ) )
	{
		// The first vertex in pair is the minimum distance
		// vertex, extract it from priority queue.
		// vertex label is stored in second of pair (it
		// has to be done this way to keep the vertices
		// sorted distance (distance must be first item
		// in pair)
		int u = pq.top ( ) .second ;
		pq.pop ( ) ; 
		// Get all adjacent of u.
		for ( auto x : adj [ u ] )
		{
			// Get vertex label and weight of current adjacent
			// of u.
			int v = x.first ;
			int weight = x.second ; 
			// If there is shorted path to v through u.
			if ( dist [ v ] > dist [ u ] + weight )
			{
				// Updating distance of v
				dist [ v ] = dist [ u ] + weight ;
				pq.push ( make_pair ( dist [ v ] , v ) ) ;
			}
		}
	}
	// Print shortest distances stored in dist [ ]
	printf ( "Vertex Distance from Source\n" ) ;
	for ( int i = 0 ; i < V ; ++i )
		printf ( "%d \ t \ t %d \n" , i , dist [ i ] ) ;
}
// Driver program to test methods of graph class
int main ( )
{
	int V = 9 ;
	vector < iPair > adj [  V  ]  ; 
	// making above shown graph
	addedge ( adj , 0 , 1 , 4 ) ;
	addedge ( adj , 0 , 7 , 8 ) ;
	addedge ( adj , 1 , 2 , 8 ) ;
	addedge ( adj , 1 , 7 , 11 ) ;
	addedge ( adj , 2 , 3 , 7 ) ;
	addedge ( adj , 2 , 8 , 2 ) ;
	addedge ( adj , 2 , 5 , 4 ) ;
	addedge ( adj , 3 , 4 , 9 ) ;
	addedge ( adj , 3 , 5 , 14 ) ;
	addedge ( adj , 4 , 5 , 10 ) ;
	addedge ( adj , 5 , 6 , 2 ) ;
	addedge ( adj , 6 , 7 , 1 ) ;
	addedge ( adj , 6 , 8 , 6 ) ; 
	addedge ( adj , 7 , 8 , 7 ) ;


	shortestPath ( adj , V , 0 ) ;


	return 0 ;
}

OUTPUT:

Vertex Distance from Source
0          0
1          4
2          12
3          19
4          21
5          11
6          9
7          8
8          14
…………………………………………….
Process executed in 0.11 seconds
Press any key to continue.

Explanation:

The heap (or priority queue) is always suggested for Dijkstra's method since the needed actions (extract minimum and reduce key) fit the heap's expertise (or priority queue). The issue is that priority queue does not support the decrease key. To fix the problem, don't update the key; instead, make a new duplicate of it. As a result, several occurrences of the same vertex are allowed in the priority queue.


Related Topics

C++ program to read string using cin.getline()

C++ program to read string using cin.getline() C++ getline() is a standard library feature for reading a string or a line from an input source. A getline() function gets characters from...

3 minutes read.

Compile Time Polymorphism in C++

What is Polymorphism? Polymorphism refers to the existence of various forms. Polymorphism can be simply defined as a message's capacity to be presented in multiple forms. One application of polymorphism in...

4 minutes read.

Difference between Two Sets in C++

The distinction between the two sets is made up of the components that are present in the first set but absent from the second set. The function consistently duplicates the...

3 minutes read.

Top 14 Best Free C++ IDE (Editor & Compiler) for Windows in 2024

Bjarne Stroustrup created the all-purpose object-oriented programming language C++. To develop C++ programs, there are various Integrated Development Environments (IDE) that offer prewritten code templates. These programs automatically modify the...

6 minutes read.

C++ Program to find the largest number formed from an array

Given an array, write a program to find the largest number that will be formed from the elements of the array. Arrangement should be done in such a way that...

4 minutes read.

Char Array to String in C++

Regardless of the programming language you use, data structure is critical to the success of your project. Although each programming language has its own collection of data structures, C++ contains a...

4 minutes read.

How to enter a name in C++

A name is a string or array of characters or letters. The string is one of the most helpful data types offered by the C++ library. A string helps the...

4 minutes read.

C++ STL (Standard Template Library)

Introduction C++ is a flexible type and general proposed programming language. So we need a standard library that supports C++. C++ STL (Standard Template Library) is a collection of templates that...

6 minutes read.

Reserved Keywords in C++

What are reserved keywords in C++? There are a few keywords that cannot be used as identifiers as those words are reserved for some other purposes, such keywords are called reserved...

15 minutes read.

C++ Friend Functions

In C++, friends are special functions that are not a part of a class yet have access to its private and protected members. The friend keyword is used to declare...

4 minutes read.

Features and Use of Pointers in C/C++

What is a pointer? A pointer is mainly used to store the address of another variable. The * operator creates a pointer variable, which points to a data type (like an...

7 minutes read.

Single Handling in C++

Introduction: Single handling in C++ refers to a technique for processing multiple events or requests with a single function or handler rather than creating separate functions for each task. This allows...

5 minutes read.

4-Dimensional Array in C/C++

A four-dimensional (4D) array is an array of three-dimensional (3D) arrays, or in other words we can say that a 4- dimensional array is an array of arrays of arrays...

3 minutes read.

Sliding Window Technique in C++

Sliding Window Technique or Window Sliding Technique is a computational technique that is mainly used to reduce the use of nested loop and replace it with a single loop. It...

4 minutes read.

Initialize Array of objects with parameterized constructors in C++

Initialize Array of objects with parameterized constructors in C++ When a class is defined, only the specification for the object is specified; no memory or capacity is allocated. You need to...

3 minutes read.

Roadmap to C++ Programming

Introduction There are so many programming languages available in the market, but among them, C++ is something that never lost its charm. It has a powerful impact on the programming world....

4 minutes read.

C++ Queue

C++ queue: Queue in C++ is also a container adapter with the functionality of a queue. Queue is just the opposite of the stack in C++ because stack works on...

4 minutes read.

Difference between "int main( ) and int main(void)" in C/C++

int main( ) function In the C/C++ programming language, int main() indicates a function that returns an integer at the end of the program execution. In general, a value of '0' indicates...

3 minutes read.

C++ Range-based For Loop

In C++ language, the range-based for loop was added, which is far superior than the ordinary For loop. The implementation of a range-based for loop doesn't really need much code. It's a...

4 minutes read.

Loops in C++

A loop statement in most programming languages allows us to execute a statement or a collection of statements numerous times. Control structures of programming languages vary, allowing for more complex...

6 minutes read.