×

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

Template Specialization in C++

Template is a feature of C++. With the help of a template, we can write the code only once and use that code multiple times. For example, there is a...

4 minutes read.

Structure of C++ Program

Many people believe that C++, an object-oriented programming (OOP) language, is the finest language for developing demanding applications. A superset of the C language is C++. Java, a closely comparable...

4 minutes read.

C++ Data Abstraction

Object-oriented programming (OOP) provides a number of characteristics that enable programmers to design programmes based on a variety of ideas, reducing errors and increasing program flexibility. The abstraction of data...

7 minutes read.

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...

5 minutes read.

C++ Goto

In this article, we will discuss the C++ goto statement with its syntax, use, key features, key points, pseudo code, and examples. What is the goto statement in C++? In C++, the...

4 minutes read.

New Operator in C++

Dynamic memory allocation in C++ means manually allocating the memory by the developer duing run-time. The dynamic memory is allocated in the heap section of the RAM, whereas the static...

3 minutes read.

Leap Year Program in C++

What is a Leap Year? A solar year is the length of time that it takes for Earth to orbit the Sun - approximately 365.25 days. In a calendar year, we...

4 minutes read.

C++ Continue

In C++, the continue statement is a useful tool for avoiding specific scenarios without breaking the loop. It is employed inside loops to move directly to the following iteration and...

4 minutes read.

Stringstream in C++ and its applications

In this tutorial, we will explore what the stringstream in C++ is. We will also learn its application. What is stringstream? With the aid of a stringstream, user can read from a...

2 minutes read.

C++ File Handling

File handling is a mechanism that manipulates the data stored in files. File handling store output data from the program to external file and read file data to the program. There...

3 minutes read.

How to find the length of the vector in C++

Like dynamic arrays, vectors can automatically adjust their size when an element is added or removed, and the container manages its storage. Because vector items are stored in contiguous storage, iterators...

3 minutes read.

C++ Pipe Tutorial

A pipe is a mechanism for inter-process communication (IPC) in a Unix-like operating system. It allows two or more processes to communicate with each other by sending and receiving data...

3 minutes read.

Approach in C++

Object oriented programming languages like Java or C++ use a bottom-up approach that identifies each object first.  In the bottom-up approach, we create a small problem first, and try to...

6 minutes read.

C++ Variable

In this article, we will discuss variables in C++ with their types and examples. What are Variables? Variables are specific memory storage spaces that hold a value. During the execution of a...

4 minutes read.

What does Buffer Flush mean in C++

A buffer flush, to explain simple layman's terms, is nothing but the transfer of computer data which is being stored in a rentable temporary memory of your computer running either...

3 minutes read.

10 Best C and C++ Books for Beginners & Advanced Programmers

If you want to become a skilled software developer, you should never stop learning, whether you're a working professional or a student. Why, therefore, only C or C++? The fundamental...

6 minutes read.

C++ Program to Implement Shell Sort

    C++ Program to Implement Shell Sort shell sort is basically an Insertion Sort variant. In the insertion sort, we only transfer elements ahead of one location. Many movements are involved...

2 minutes read.

Division in C++

C++ Division Arithmetic Operation In C++ the arithmetic operator / is used for division. This operator takes two operands and returns the result of dividing the left operand by the right...

3 minutes read.

C++ Break

In this article, we will discuss the C++ Break statement with its syntax, algorithm, pseudocode, and examples. The C++ break statement also terminates the currently active loop or switch statement immediately....

4 minutes read.

Palindrome using Do-while loop in C++

What is Palindrome? A palindrome is a word, number, phrase, or other sequence of letters that reads the same backward as forward, such as 101 or MOM. Like other programming languages, C++...

5 minutes read.