Dijkstra's Algorithm for Competitive Programming
Last Updated :
19 May, 2024
Dijkstra's algorithm, devised by computer scientist Edsger Dijkstra, is a fundamental graph search algorithm used to find the shortest path between nodes in a weighted graph. In this article, we will learn about how Dijkstra's algorithm can be used for solving problems in Competitive Programming.

What is Dijkstra's Algorithm?
Dijkstra’s Algorithm is a Single-Source Shortest Path algorithm, i.e., given a source vertex it finds the shortest path from the source to all other vertices. The idea is to generate a SPT (Shortest Path Tree) with a given source as a root and with two sets,Â
- one set contains vertices included in the shortest-path tree,Â
- other set includes vertices not yet included in the shortest-path tree.Â
At every step of the algorithm, find a vertex that is in the other set (set not yet included) and has a minimum distance from the source.
Dijkstra’s Algorithm uses a Greedy approach to find the shortest path from the source to all other vertices. It starts from the source vertex and maintains a set of vertices with known minimum distances from the source. The key idea of the Greedy strategy is selecting the vertex with the currently shortest known distance from the Source and exploring it next.
Implementation of Dijkstra's Algorithm:
1. Dense Graph
For Dense Graphs where m is approximately equal to n2 (m= no. of edges and n= no. of vertices) it is optimal to follow the following approach:
- Create two arrays dis[] and vis[]. vis[] is a Boolean array where vis[v] tells whether the vertex v is marked or not (whether the shortest distance from source to vertex v is determined or not) and dis[v] represents minimum distance from source to a marked vertex v.
- Set dis[src]=0 and vis[src]=1, where src is the source node.
- Perform n iterations,
- On each iteration, choose a vertex v with the smallest value of dis[v] and that is unmarked (vis[v] is false). Set vis[v] as true.
- Iterate over all edges (v->u) and set dis[u]=min(dis[u], dis[v]+w), where w is weight of edge from vertex v to u.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
// Dijkstra's algorithm for dense graphs
vector<int> dijkstra(int n,
vector<vector<pair<int, int> > >& adj,
int src)
{
// Array to store minimum distances
vector<int> dis(n + 1, INT_MAX);
// Array to mark visited vertices
vector<bool> vis(n + 1, false);
// Set the distance to the source as 0
dis[src] = 0;
for (int i = 0; i < n; i++) {
int v = -1;
for (int j = 1; j <= n; j++) {
if (!vis[j] && (v == -1 || dis[j] < dis[v]))
v = j;
}
if (dis[v] == INT_MAX)
break;
// Mark vertex v as visited
vis[v] = true;
for (auto edge : adj[v]) {
// Neighbor vertex
int x = edge.first;
// Edge weight
int wt = edge.second;
// Update the distance if a shorter path is
// found
if (dis[v] + wt < dis[x]) {
dis[x] = dis[v] + wt;
}
}
}
// Return the array of minimum distances
return dis;
}
int main()
{
// Number of vertices
int n = 6;
// Adjacency list
vector<vector<pair<int, int> > > adj(n + 1);
// Example: adding edges to the adjacency list
// Edge from vertex 1 to 2 with weight 3
adj[1].push_back({ 2, 3 });
// Edge from vertex 1 to 3 with weight 5
adj[1].push_back({ 3, 5 });
// Edge from vertex 2 to 3 with weight 1
adj[2].push_back({ 3, 1 });
// Edge from vertex 3 to 4 with weight 2
adj[3].push_back({ 4, 2 });
// Edge from vertex 2 to 4 with weight 7
adj[2].push_back({ 4, 7 });
int src = 1; // Source vertex
vector<int> distances = dijkstra(n, adj, src);
// Print the minimum distances from the source to all
// other vertices
for (int i = 1; i <= n; i++) {
cout << "Minimum distance from vertex " << src
<< " to " << i << " is " << distances[i]
<< "\n";
}
return 0;
}
Java
// Java Implementation
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
// Dijkstra's algorithm for dense graphs
static List<Integer> dijkstra(int n, List<List<Pair>> adj, int src) {
// Array to store minimum distances
int[] dis = new int[n + 1];
Arrays.fill(dis, Integer.MAX_VALUE);
// Array to mark visited vertices
boolean[] vis = new boolean[n + 1];
// Set the distance to the source as 0
dis[src] = 0;
for (int i = 0; i < n; i++) {
int v = -1;
for (int j = 1; j <= n; j++) {
if (!vis[j] && (v == -1 || dis[j] < dis[v]))
v = j;
}
if (dis[v] == Integer.MAX_VALUE)
break;
// Mark vertex v as visited
vis[v] = true;
for (Pair edge : adj.get(v)) {
// Neighbor vertex
int x = edge.vertex;
// Edge weight
int wt = edge.weight;
// Update the distance if a shorter path is found
if (dis[v] + wt < dis[x]) {
dis[x] = dis[v] + wt;
}
}
}
// Return the array of minimum distances
List<Integer> result = new ArrayList<>();
for (int i = 0; i <= n; i++) {
result.add(dis[i]);
}
return result;
}
public static void main(String[] args) {
// Number of vertices
int n = 6;
// Adjacency list
List<List<Pair>> adj = new ArrayList<>();
for (int i = 0; i <= n; i++) {
adj.add(new ArrayList<>());
}
// Example: adding edges to the adjacency list
// Edge from vertex 1 to 2 with weight 3
adj.get(1).add(new Pair(2, 3));
// Edge from vertex 1 to 3 with weight 5
adj.get(1).add(new Pair(3, 5));
// Edge from vertex 2 to 3 with weight 1
adj.get(2).add(new Pair(3, 1));
// Edge from vertex 3 to 4 with weight 2
adj.get(3).add(new Pair(4, 2));
// Edge from vertex 2 to 4 with weight 7
adj.get(2).add(new Pair(4, 7));
int src = 1; // Source vertex
List<Integer> distances = dijkstra(n, adj, src);
// Print the minimum distances from the source to all other vertices
for (int i = 1; i <= n; i++) {
System.out.println("Minimum distance from vertex " +
src + " to " + i + " is " + distances.get(i));
}
}
static class Pair {
int vertex;
int weight;
Pair(int v, int w) {
vertex = v;
weight = w;
}
}
}
// This code is contributed by Sakshi
Python
import sys
# Dijkstra's algorithm for dense graphs
def dijkstra(n, adj, src):
# Array to store minimum distances
dis = [sys.maxsize] * (n + 1)
# Array to mark visited vertices
vis = [False] * (n + 1)
# Set the distance to the source as 0
dis[src] = 0
for _ in range(n):
v = -1
for j in range(1, n + 1):
if not vis[j] and (v == -1 or dis[j] < dis[v]):
v = j
if dis[v] == sys.maxsize:
break
# Mark vertex v as visited
vis[v] = True
for edge in adj[v]:
# Neighbor vertex
x = edge[0]
# Edge weight
wt = edge[1]
# Update the distance if a shorter path is found
if dis[v] + wt < dis[x]:
dis[x] = dis[v] + wt
# Return the array of minimum distances
return dis
if __name__ == "__main__":
# Number of vertices
n = 6
# Adjacency list
adj = [[] for _ in range(n + 1)]
# Example: adding edges to the adjacency list
# Edge from vertex 1 to 2 with weight 3
adj[1].append((2, 3))
# Edge from vertex 1 to 3 with weight 5
adj[1].append((3, 5))
# Edge from vertex 2 to 3 with weight 1
adj[2].append((3, 1))
# Edge from vertex 3 to 4 with weight 2
adj[3].append((4, 2))
# Edge from vertex 2 to 4 with weight 7
adj[2].append((4, 7))
src = 1 # Source vertex
distances = dijkstra(n, adj, src)
# Print the minimum distances from the source to all other vertices
for i in range(1, n + 1):
print("Minimum distance from vertex", src, "to", i, "is", distances[i])
C#
using System;
using System.Collections.Generic;
class Program
{
// Dijkstra's algorithm for dense graphs
static List<int> Dijkstra(int n, List<List<Tuple<int, int>>> adj, int src)
{
// Array to store minimum distances
List<int> dis = new List<int>(new int[n + 1]);
for (int i = 0; i <= n; i++)
{
dis[i] = int.MaxValue;
}
// Array to mark visited vertices
bool[] vis = new bool[n + 1];
// Set the distance to the source as 0
dis[src] = 0;
for (int i = 0; i < n; i++)
{
int v = -1;
for (int j = 1; j <= n; j++)
{
if (!vis[j] && (v == -1 || dis[j] < dis[v]))
v = j;
}
if (dis[v] == int.MaxValue)
break;
// Mark vertex v as visited
vis[v] = true;
foreach (var edge in adj[v])
{
// Neighbor vertex
int x = edge.Item1;
// Edge weight
int wt = edge.Item2;
// Update the distance if a shorter path is found
if (dis[v] + wt < dis[x])
{
dis[x] = dis[v] + wt;
}
}
}
// Return the list of minimum distances
return dis;
}
static void Main()
{
// Number of vertices
int n = 6;
// Adjacency list
List<List<Tuple<int, int>>> adj = new List<List<Tuple<int, int>>>(n + 1);
for (int i = 0; i <= n; i++)
{
adj.Add(new List<Tuple<int, int>>());
}
// Example: adding edges to the adjacency list
// Edge from vertex 1 to 2 with weight 3
adj[1].Add(new Tuple<int, int>(2, 3));
// Edge from vertex 1 to 3 with weight 5
adj[1].Add(new Tuple<int, int>(3, 5));
// Edge from vertex 2 to 3 with weight 1
adj[2].Add(new Tuple<int, int>(3, 1));
// Edge from vertex 3 to 4 with weight 2
adj[3].Add(new Tuple<int, int>(4, 2));
// Edge from vertex 2 to 4 with weight 7
adj[2].Add(new Tuple<int, int>(4, 7));
int src = 1; // Source vertex
List<int> distances = Dijkstra(n, adj, src);
// Print the minimum distances from the source to all other vertices
for (int i = 1; i <= n; i++)
{
Console.WriteLine($"Minimum distance from vertex {src} to {i} is {distances[i]}");
}
}
}
JavaScript
// JavaScript Implementation
// Function to implement Dijkstra's algorithm for dense graphs
function dijkstra(n, adj, src) {
// Array to store minimum distances
let dis = new Array(n + 1).fill(Number.MAX_SAFE_INTEGER);
// Array to mark visited vertices
let vis = new Array(n + 1).fill(false);
// Set the distance to the source as 0
dis[src] = 0;
for (let i = 0; i < n; i++) {
let v = -1;
for (let j = 1; j <= n; j++) {
if (!vis[j] && (v == -1 || dis[j] < dis[v]))
v = j;
}
if (dis[v] == Number.MAX_SAFE_INTEGER)
break;
// Mark vertex v as visited
vis[v] = true;
for (let edge of adj[v]) {
// Neighbor vertex
let x = edge.vertex;
// Edge weight
let wt = edge.weight;
// Update the distance if a shorter path is found
if (dis[v] + wt < dis[x]) {
dis[x] = dis[v] + wt;
}
}
}
// Return the array of minimum distances
return dis.slice(1); // Remove the first element (index 0)
}
// Example usage
// Number of vertices
let n = 6;
// Adjacency list
let adj = new Array(n + 1).fill(null).map(() => []);
// Example: adding edges to the adjacency list
// Edge from vertex 1 to 2 with weight 3
adj[1].push({ vertex: 2, weight: 3 });
// Edge from vertex 1 to 3 with weight 5
adj[1].push({ vertex: 3, weight: 5 });
// Edge from vertex 2 to 3 with weight 1
adj[2].push({ vertex: 3, weight: 1 });
// Edge from vertex 3 to 4 with weight 2
adj[3].push({ vertex: 4, weight: 2 });
// Edge from vertex 2 to 4 with weight 7
adj[2].push({ vertex: 4, weight: 7 });
let src = 1; // Source vertex
let distances = dijkstra(n, adj, src);
// Print the minimum distances from the source to all other vertices
for (let i = 1; i <= n; i++) {
console.log(`Minimum distance from vertex ${src} to ${i} is ${distances[i - 1]}`);
}
// Defining Pair class
class Pair {
constructor(v, w) {
this.vertex = v;
this.weight = w;
}
}
OutputMinimum distance from vertex 1 to 1 is 0
Minimum distance from vertex 1 to 2 is 3
Minimum distance from vertex 1 to 3 is 4
Minimum distance from vertex 1 to 4 is 6
Minimum distance from vertex 1 to 5 ...
Time Complexity: O(n2+m), where n is the number of vertices and m is the number of edges in the given graph.
Auxiliary Space: O(n)
2. Sparse Graph
 For Sparse Graph where m is very much smaller than n2, a slightly different implementation is used which is the most optimal in this case:
- In above implementation of dense graph, for selecting the vertex v with smallest value of dis[v], we iterated over all the vertices leading to complexity of O(n) for this operation. Instead of this, we use a data structure (set or priority queue) to extract the vertex with minimum value of dis[v], leading to complexity of O(log n) for this operation.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
// Dijkstra algorithm for sparse graphs
vector<int> dijkstra(int n,
vector<vector<pair<int, int> > >& adj,
int src)
{
// priority_queue to store extract vertex with minimum
// distance
priority_queue<pair<int, int>, vector<pair<int, int> >,
greater<pair<int, int> > >
p;
// Array to store minimum distances
vector<int> dis(n + 1, INT_MAX);
// Push the source vertex with a distance of 0
p.push(make_pair(0, src));
// Set the distance to the source as 0
dis[src] = 0;
while (!p.empty()) {
int curr = p.top().second;
int l = p.top().first;
p.pop();
// Skip if this vertex has already been processed
// with a shorter distance
if (dis[curr] != l) {
continue;
}
for (auto x : adj[curr]) {
int d = x.first; // Neighbor vertex
int len = x.second; // Edge weight
// Update the distance if a shorter path is
// found
if (dis[d] > len + dis[curr]) {
dis[d] = len + dis[curr];
// Push the updated distance and vertex
p.push(make_pair(dis[d], d));
}
}
}
// Return the array of minimum distances
return dis;
}
// Driver Code
int main()
{
int n = 6; // Number of vertices
// Adjacency list
vector<vector<pair<int, int> > > adj(n + 1);
// Example: adding edges to the adjacency list
// Edge from vertex 1 to 2 with weight 3
adj[1].push_back({ 2, 3 });
// Edge from vertex 1 to 3 with weight 5
adj[1].push_back({ 3, 5 });
// Edge from vertex 2 to 3 with weight 1
adj[2].push_back({ 3, 1 });
// Edge from vertex 3 to 4 with weight 2
adj[3].push_back({ 4, 2 });
// Edge from vertex 2 to 4 with weight 7
adj[2].push_back({ 4, 7 });
int src = 1; // Source vertex
vector<int> distances = dijkstra(n, adj, src);
// Print the minimum distances from the source to all
// other vertices
for (int i = 1; i <= n; i++) {
cout << "Minimum distance from vertex " << src
<< " to " << i << " is " << distances[i]
<< "\n";
}
return 0;
}
Java
import java.util.*;
public class Dijkstra {
// Pair class to store vertex and weight
static class Pair implements Comparable<Pair> {
int vertex, weight;
// Constructor
public Pair(int vertex, int weight) {
this.vertex = vertex;
this.weight = weight;
}
// Comparator for sorting in priority queue based on weight
@Override
public int compareTo(Pair other) {
return Integer.compare(this.weight, other.weight);
}
}
// Dijkstra's algorithm to find the shortest path from src to all other vertices
public static ArrayList<Integer> dijkstra(int n, ArrayList<ArrayList<Pair>> adj, int src) {
PriorityQueue<Pair> pq = new PriorityQueue<>();
ArrayList<Integer> dis = new ArrayList<>(Collections.nCopies(n + 1, Integer.MAX_VALUE));
// Initialize the source distance to 0 and add to priority queue
dis.set(src, 0);
pq.add(new Pair(src, 0));
while (!pq.isEmpty()) {
Pair curr = pq.poll(); // Get and remove the minimum weight pair
int vertex = curr.vertex;
int weight = curr.weight;
// Skip processing if we have already found a better path
if (dis.get(vertex) < weight) continue;
// Explore all adjacent vertices
for (Pair neighbour : adj.get(vertex)) {
// Relaxation step: Check if a better path is found
if (dis.get(neighbour.vertex) > weight + neighbour.weight) {
dis.set(neighbour.vertex, weight + neighbour.weight); // Update distance
pq.add(new Pair(neighbour.vertex, dis.get(neighbour.vertex))); // Add new pair to the queue
}
}
}
return dis; // Return the list of minimum distances
}
public static void main(String[] args) {
int n = 6; // Number of vertices
ArrayList<ArrayList<Pair>> adj = new ArrayList<>();
// Initialize adjacency list
for (int i = 0; i <= n; i++) {
adj.add(new ArrayList<>());
}
// Adding edges to the adjacency list
adj.get(1).add(new Pair(2, 3));
adj.get(1).add(new Pair(3, 5));
adj.get(2).add(new Pair(3, 1));
adj.get(3).add(new Pair(4, 2));
adj.get(2).add(new Pair(4, 7));
int src = 1; // Source vertex
ArrayList<Integer> distances = dijkstra(n, adj, src); // Compute shortest paths
// Print the distances
for (int i = 1; i <= n; i++) {
System.out.println("Minimum distance from vertex " + src + " to " + i + " is " + distances.get(i));
}
}
}
Python
import heapq
# Pair class to store vertex and weight
class Pair:
def __init__(self, vertex, weight):
self.vertex = vertex
self.weight = weight
# Comparator for sorting in priority queue based on weight
def __lt__(self, other):
return self.weight < other.weight
# Dijkstra's algorithm to find the shortest path from src to all other vertices
def dijkstra(n, adj, src):
pq = []
dis = [float('inf')] * (n + 1)
# Initialize the source distance to 0 and add to priority queue
dis[src] = 0
heapq.heappush(pq, Pair(src, 0))
while pq:
curr = heapq.heappop(pq) # Get and remove the minimum weight pair
vertex, weight = curr.vertex, curr.weight
# Skip processing if we have already found a better path
if dis[vertex] < weight:
continue
# Explore all adjacent vertices
for neighbour in adj[vertex]:
# Relaxation step: Check if a better path is found
if dis[neighbour.vertex] > weight + neighbour.weight:
dis[neighbour.vertex] = weight + neighbour.weight # Update distance
heapq.heappush(pq, Pair(neighbour.vertex, dis[neighbour.vertex])) # Add new pair to the queue
return dis # Return the list of minimum distances
if __name__ == "__main__":
n = 6 # Number of vertices
adj = [[] for _ in range(n + 1)]
# Adding edges to the adjacency list
adj[1].append(Pair(2, 3))
adj[1].append(Pair(3, 5))
adj[2].append(Pair(3, 1))
adj[3].append(Pair(4, 2))
adj[2].append(Pair(4, 7))
src = 1 # Source vertex
distances = dijkstra(n, adj, src) # Compute shortest paths
# Print the distances
for i in range(1, n + 1):
print("Minimum distance from vertex {} to {} is {}".format(src, i, distances[i]))
C#
using System;
using System.Collections.Generic;
class DijkstraAlgorithm
{
// Dijkstra algorithm for sparse graphs
static List<int> Dijkstra(int n, List<List<Tuple<int, int>>> adj, int src)
{
// Priority queue to store extracted vertex with minimum distance
PriorityQueue<Tuple<int, int>> p = new PriorityQueue<Tuple<int, int>>();
// Array to store minimum distances
List<int> dis = new List<int>(new int[n + 1]);
for (int i = 0; i <= n; i++)
dis[i] = int.MaxValue;
// Push the source vertex with a distance of 0
p.Enqueue(new Tuple<int, int>(0, src));
// Set the distance to the source as 0
dis[src] = 0;
while (p.Count > 0)
{
int curr = p.Peek().Item2;
int l = p.Peek().Item1;
p.Dequeue();
// Skip if this vertex has already been processed with a shorter distance
if (dis[curr] != l)
continue;
foreach (var x in adj[curr])
{
int d = x.Item1; // Neighbor vertex
int len = x.Item2; // Edge weight
// Update the distance if a shorter path is found
if (dis[d] > len + dis[curr])
{
dis[d] = len + dis[curr];
// Push the updated distance and vertex
p.Enqueue(new Tuple<int, int>(dis[d], d));
}
}
}
// Return the array of minimum distances
return dis;
}
// Driver Code
static void Main()
{
int n = 6; // Number of vertices
// Adjacency list
List<List<Tuple<int, int>>> adj = new List<List<Tuple<int, int>>>(n + 1);
// Initialize adjacency list
for (int i = 0; i <= n; i++)
adj.Add(new List<Tuple<int, int>>());
// Example: adding edges to the adjacency list
// Edge from vertex 1 to 2 with weight 3
adj[1].Add(new Tuple<int, int>(2, 3));
// Edge from vertex 1 to 3 with weight 5
adj[1].Add(new Tuple<int, int>(3, 5));
// Edge from vertex 2 to 3 with weight 1
adj[2].Add(new Tuple<int, int>(3, 1));
// Edge from vertex 3 to 4 with weight 2
adj[3].Add(new Tuple<int, int>(4, 2));
// Edge from vertex 2 to 4 with weight 7
adj[2].Add(new Tuple<int, int>(4, 7));
int src = 1; // Source vertex
List<int> distances = Dijkstra(n, adj, src);
// Print the minimum distances from the source to all other vertices
for (int i = 1; i <= n; i++)
{
Console.WriteLine($"Minimum distance from vertex {src} to {i} is {distances[i]}");
}
}
}
// Priority Queue implementation
public class PriorityQueue<T>
{
private List<T> heap;
private Comparison<T> compare;
public int Count { get { return heap.Count; } }
public PriorityQueue() : this(Comparer<T>.Default) { }
public PriorityQueue(IComparer<T> comparer) : this(16, comparer.Compare) { }
public PriorityQueue(Comparison<T> comparison) : this(16, comparison) { }
public PriorityQueue(int capacity, Comparison<T> comparison)
{
this.heap = new List<T>(capacity);
this.compare = comparison;
}
public void Enqueue(T item)
{
heap.Add(item);
int i = Count - 1;
while (i > 0)
{
int j = (i - 1) / 2;
if (compare(heap[j], item) <= 0)
break;
heap[i] = heap[j];
i = j;
}
heap[i] = item;
}
public T Dequeue()
{
T ret = heap[0];
int last = Count - 1;
T x = heap[last];
int i = 0;
while (i * 2 + 1 < last)
{
int a = i * 2 + 1;
int b = i * 2 + 2;
if (b < last && compare(heap[a], heap[b]) > 0) a = b;
if (compare(heap[a], x) >= 0)
break;
heap[i] = heap[a];
i = a;
}
heap[i] = x;
heap.RemoveAt(last);
return ret;
}
public T Peek()
{
return heap[0];
}
}
JavaScript
class PriorityQueue {
constructor() {
this.queue = [];
}
enqueue(vertex, weight) {
this.queue.push({ vertex, weight });
this.queue.sort((a, b) => a.weight - b.weight);
}
dequeue() {
return this.queue.shift();
}
isEmpty() {
return this.queue.length === 0;
}
}
function dijkstra(n, adj, src) {
const p = new PriorityQueue();
const dis = new Array(n + 1).fill(Number.MAX_VALUE);
p.enqueue(src, 0);
dis[src] = 0;
while (!p.isEmpty()) {
const { vertex: curr, weight: l } = p.dequeue();
if (dis[curr] != l) {
continue;
}
for (const { vertex: d, weight: len } of adj[curr]) {
if (dis[d] > len + dis[curr]) {
dis[d] = len + dis[curr];
p.enqueue(d, dis[d]);
}
}
}
return dis;
}
// Driver code
const n = 6; // Number of vertices
const adj = Array.from({ length: n + 1 }, () => []);
// Example: adding edges to the adjacency list
adj[1].push({ vertex: 2, weight: 3 });
adj[1].push({ vertex: 3, weight: 5 });
adj[2].push({ vertex: 3, weight: 1 });
adj[3].push({ vertex: 4, weight: 2 });
adj[2].push({ vertex: 4, weight: 7 });
const src = 1; // Source vertex
const distances = dijkstra(n, adj, src);
// Print the minimum distances from the source to all other vertices
for (let i = 1; i <= n; i++) {
console.log(`Minimum distance from vertex ${src} to ${i} is ${distances[i]}`);
}
OutputMinimum distance from vertex 1 to 1 is 0
Minimum distance from vertex 1 to 2 is 3
Minimum distance from vertex 1 to 3 is 4
Minimum distance from vertex 1 to 4 is 6
Minimum distance from vertex 1 to 5 ...
Time Complexity: O(mlogn), where n is the number of vertices and m is the number of edges in the given graph.
Auxiliary Space: O(m)
How to solve problems that involve Dijkstra's Algorithm:
Below are the few problems that will help to identify how or when can we apply Dijkstra's Algorithm in competitive programming problem:
Problem 1: You are given an undirected weighted graph with   N vertices and M edges. You can make the weight of any one edge zero. The task is to compute shortest path from vertex 1 to vertex N such that you can reduce weight of any edge to 0.
Let's see how we can apply Dijkstra's Algorithm to above problem:
Observation: The above problem is a shortest path problem but with modification that weight of any one edge can be made 0. Now suppose we are making the weight of edge vertex v and u to 0, then there we get two cases:
Case 1: 1->v->u->N: We need to know the minimum distance between from vertex 1 to vertex v and vertex N to vertex u.
Case 2: 1->u->v->N: We need to know the minimum distance between from vertex 1 to vertex u and vertex N to vertex v.
Applying Dijkstra's Algorithm: To compute the results of above two cases optimally we use Dijkstra's Algorithm from vertex 1 and vertex N, since we need to know the minimum distance from vertex 1 and N to every other vertex.
Final Answer: Our final answer will be the minimum of:
min(dis1[v]+dis2[u], dis1[u]+dis2[v]), for all edges(v-u), where dis1[a] represents the minimum distance from vertex 1 to vertex a and dis2[a] represents the minimum distance from vertex N to vertex a.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
// Dijkstra's algorithm function to compute minimum
// distances
vector<int> Dijkstra(int n, int m,
vector<vector<pair<int, int> > >& adj,
int src)
{
// Priority queue for min-heap
priority_queue<pair<int, int>, vector<pair<int, int> >,
greater<pair<int, int> > >
p;
// Initialize distances
vector<int> distance(n + 1, INT_MAX);
// Push the source vertex with a distance of 0
p.push(make_pair(0, src));
// Set the distance of the source vertex to 0
distance[src] = 0;
while (!p.empty()) {
int curr = p.top().second;
int l = p.top().first;
p.pop();
// Skip if this vertex has already been processed
// with a shorter distance
if (distance[curr] != l) {
continue;
}
// Explore neighbors and update distances
for (auto x : adj[curr]) {
// Neighbor vertex
int d = x.first;
// Edge weight
int len = x.second;
// Update the distance if a shorter path is
// found
if (distance[d] > len + distance[curr]) {
distance[d] = len + distance[curr];
// Push the updated distance and vertex
p.push(make_pair(distance[d], d));
}
}
}
return distance;
}
// Function to solve the problem
void solve(int n, int m, vector<vector<int> >& edges)
{
// Adjacency list for edges
vector<vector<pair<int, int> > > adj(n + 1);
// Build the adjacency list for edges
for (int i = 0; i < m; i++) {
int x = edges[i][0], y = edges[i][1],
z = edges[i][2];
adj[x].push_back({ y, z });
adj[y].push_back({ x, z });
}
// Compute minimum distances from vertex 1 and vertex N
vector<int> dis1 = Dijkstra(n, m, adj, 1);
vector<int> dis2 = Dijkstra(n, m, adj, n);
int ans = INT_MAX;
// Iterate through all edges to find the minimum cost of
// reducing an edge to 0
for (int i = 0; i < m; i++) {
int v = edges[i][0], u = edges[i][1];
// Calculate the cost of reducing edge (v, u) to 0
ans = min(
ans, min(dis1[v] + dis2[u], dis1[u] + dis2[v]));
}
// Output the minimum cost
cout << ans << "\n";
}
int main()
{
int n = 4, m = 4;
// Edges as (vertex1, vertex2, weight)
vector<vector<int> > edges = {
{ 1, 2, 3 }, { 2, 3, 1 }, { 1, 3, 7 }, { 3, 4, 2 }
};
// Call the solve function to find the answer
solve(n, m, edges);
return 0;
}
Java
import java.util.*;
public class DijkstraAlgorithm {
// Dijkstra's algorithm function to compute minimum
// distances
public static List<Integer>
dijkstra(int n, int m, List<List<Pair> > adj, int src)
{
// Priority queue for min-heap
PriorityQueue<Pair> p = new PriorityQueue<>(
Comparator.comparingInt(pair -> pair.first));
// Initialize distances
List<Integer> distance = new ArrayList<>(
Collections.nCopies(n + 1, Integer.MAX_VALUE));
// Push the source vertex with a distance of 0
p.add(new Pair(0, src));
// Set the distance of the source vertex to 0
distance.set(src, 0);
while (!p.isEmpty()) {
int curr = p.peek().second;
int l = p.peek().first;
p.poll();
// Skip if this vertex has already been
// processed with a shorter distance
if (!distance.get(curr).equals(l)) {
continue;
}
// Explore neighbors and update distances
for (Pair x : adj.get(curr)) {
// Neighbor vertex
int d = x.first;
// Edge weight
int len = x.second;
// Update the distance if a shorter path is
// found
if (distance.get(d)
> len + distance.get(curr)) {
distance.set(d,
len + distance.get(curr));
// Push the updated distance and vertex
p.add(new Pair(distance.get(d), d));
}
}
}
return distance;
}
// Function to solve the problem
public static void solve(int n, int m,
List<List<Integer> > edges)
{
// Adjacency list for edges
List<List<Pair> > adj = new ArrayList<>();
for (int i = 0; i <= n; i++) {
adj.add(new ArrayList<>());
}
// Build the adjacency list for edges
for (int i = 0; i < m; i++) {
int x = edges.get(i).get(0);
int y = edges.get(i).get(1);
int z = edges.get(i).get(2);
adj.get(x).add(new Pair(y, z));
adj.get(y).add(new Pair(x, z));
}
// Compute minimum distances from vertex 1 and
// vertex N
List<Integer> dis1 = dijkstra(n, m, adj, 1);
List<Integer> dis2 = dijkstra(n, m, adj, n);
int ans = Integer.MAX_VALUE;
// Iterate through all edges to find the minimum
// cost of reducing an edge to 0
for (int i = 0; i < m; i++) {
int v = edges.get(i).get(0);
int u = edges.get(i).get(1);
// Calculate the cost of reducing edge (v, u) to
// 0
ans = Math.min(
ans, Math.min(dis1.get(v) + dis2.get(u),
dis1.get(u) + dis2.get(v)));
}
// Output the minimum cost
System.out.println(ans);
}
public static void main(String[] args)
{
int n = 4, m = 4;
// Edges as (vertex1, vertex2, weight)
List<List<Integer> > edges = Arrays.asList(
Arrays.asList(1, 2, 3), Arrays.asList(2, 3, 1),
Arrays.asList(1, 3, 7), Arrays.asList(3, 4, 2));
// Call the solve function to find the answer
solve(n, m, edges);
}
}
// Pair class to store (vertex, weight) pairs
class Pair {
int first, second;
Pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// This code is contributed by Aman.
Python
import heapq
# Dijkstra's algorithm function to compute minimum distances
def Dijkstra(n, m, adj, src):
# Priority queue for min-heap
p = []
# Initialize distances
distance = [float('inf')] * (n + 1)
# Push the source vertex with a distance of 0
heapq.heappush(p, (0, src))
# Set the distance of the source vertex to 0
distance[src] = 0
while p:
l, curr = heapq.heappop(p)
# Skip if this vertex has already been processed with a shorter distance
if distance[curr] != l:
continue
# Explore neighbors and update distances
for d, len in adj[curr]:
# Update the distance if a shorter path is found
if distance[d] > len + distance[curr]:
distance[d] = len + distance[curr]
# Push the updated distance and vertex
heapq.heappush(p, (distance[d], d))
return distance
# Function to solve the problem
def solve(n, m, edges):
# Adjacency list for edges
adj = [[] for _ in range(n + 1)]
# Build the adjacency list for edges
for i in range(m):
x, y, z = edges[i]
adj[x].append((y, z))
adj[y].append((x, z))
# Compute minimum distances from vertex 1 and vertex N
dis1 = Dijkstra(n, m, adj, 1)
dis2 = Dijkstra(n, m, adj, n)
ans = float('inf')
# Iterate through all edges to find the minimum cost of reducing an edge to 0
for i in range(m):
v, u, _ = edges[i]
# Calculate the cost of reducing edge (v, u) to 0
ans = min(ans, min(dis1[v] + dis2[u], dis1[u] + dis2[v]))
# Output the minimum cost
print(ans)
n = 4
m = 4
# Edges as (vertex1, vertex2, weight)
edges = [
[1, 2, 3], [2, 3, 1], [1, 3, 7], [3, 4, 2]
]
solve(n, m, edges)
C#
using System;
using System.Collections.Generic;
public class WeightedEdge {
public int Vertex
{
get;
set;
}
public int Weight
{
get;
set;
}
}
public class Solution {
// Dijkstra's algorithm function to compute minimum
// distances
public static List<int>
Dijkstra(int n, int m, List<List<WeightedEdge> > adj,
int src)
{
// Priority queue for min-heap
var p = new SortedSet<Tuple<int, int> >(
Comparer<Tuple<int, int> >.Create(
(a, b) = > a.Item1 == b.Item1
? a.Item2.CompareTo(b.Item2)
: a.Item1.CompareTo(b.Item1)));
// Initialize distances
var distance = new List<int>(new int[n + 1]);
for (int i = 0; i < n + 1; i++) {
distance[i] = int.MaxValue;
}
// Push the source vertex with a distance of 0
p.Add(new Tuple<int, int>(0, src));
distance[src] = 0;
while (p.Count > 0) {
var curr = p.Min;
p.Remove(curr);
int l = curr.Item1;
int current = curr.Item2;
// Skip if this vertex has already been
// processed with a shorter distance
if (distance[current] != l) {
continue;
}
// Explore neighbors and update distances
foreach(var x in adj[current])
{
int d = x.Vertex;
int len = x.Weight;
// Update the distance if a shorter path is
// found
if (distance[d] > len + distance[current]) {
distance[d] = len + distance[current];
p.Add(new Tuple<int, int>(distance[d],
d));
}
}
}
return distance;
}
// Function to solve the problem
public static void Solve(int n, int m,
List<List<int> > edges)
{
// Adjacency list for edges
var adj = new List<List<WeightedEdge> >(
new List<WeightedEdge>[ n + 1 ]);
for (int i = 0; i < n + 1; i++) {
adj[i] = new List<WeightedEdge>();
}
// Build the adjacency list for edges
for (int i = 0; i < m; i++) {
int x = edges[i][0], y = edges[i][1],
z = edges[i][2];
adj[x].Add(
new WeightedEdge{ Vertex = y, Weight = z });
adj[y].Add(
new WeightedEdge{ Vertex = x, Weight = z });
}
// Compute minimum distances from vertex 1 and
// vertex N
var dis1 = Dijkstra(n, m, adj, 1);
var dis2 = Dijkstra(n, m, adj, n);
int ans = int.MaxValue;
// Iterate through all edges to find the minimum
// cost of reducing an edge to 0
for (int i = 0; i < m; i++) {
int v = edges[i][0], u = edges[i][1];
// Calculate the cost of reducing edge (v, u) to
// 0
ans = Math.Min(ans,
dis1[v] + edges[i][2] + dis2[u]);
ans = Math.Min(ans,
dis1[u] + edges[i][2] + dis2[v]);
}
// Output the minimum cost
Console.WriteLine(ans);
}
public static void Main()
{
int n = 4, m = 4;
// Edges as (vertex1, vertex2, weight)
List<List<int> > edges = new List<List<int> >{
new List<int>{ 1, 2, 3 },
new List<int>{ 2, 3, 1 },
new List<int>{ 1, 3, 7 },
new List<int>{ 3, 4, 2 }
};
// Call the Solve function to find the answer
Solve(n, m, edges);
}
}
JavaScript
class MinHeap {
constructor() {
this.heap = [];
}
push(val) {
this.heap.push(val);
this.heapifyUp(this.heap.length - 1);
}
pop() {
if (this.heap.length === 0) return null;
const top = this.heap[0];
const last = this.heap.pop();
if (this.heap.length > 0) {
this.heap[0] = last;
this.heapifyDown(0);
}
return top;
}
heapifyUp(idx) {
while (idx > 0) {
const parentIdx = Math.floor((idx - 1) / 2);
if (this.heap[parentIdx][0] > this.heap[idx][0]) {
[this.heap[parentIdx], this.heap[idx]] = [this.heap[idx], this.heap[parentIdx]];
idx = parentIdx;
} else {
break;
}
}
}
heapifyDown(idx) {
while (idx < this.heap.length) {
let leftChild = 2 * idx + 1;
let rightChild = 2 * idx + 2;
let smallest = idx;
if(leftChild < this.heap.length && this.heap[leftChild][0] < this.heap[smallest][0]){
smallest = leftChild;
}
if(rightChild < this.heap.length && this.heap[rightChild][0] < this.heap[smallest][0]){
smallest = rightChild;
}
if (smallest !== idx) {
[this.heap[smallest], this.heap[idx]] = [this.heap[idx], this.heap[smallest]];
idx = smallest;
} else {
break;
}
}
}
}
function dijkstra(n, m, adj, src) {
// Priority queue for min-heap
const pq = new MinHeap();
pq.push([0, src]);
// Initialize distances
const distance = Array(n + 1).fill(Number.MAX_SAFE_INTEGER);
distance[src] = 0;
while (pq.heap.length > 0) {
const [currDist, curr] = pq.pop();
// Skip if this vertex has already been processed
// with a shorter distance
if (currDist > distance[curr]) {
continue;
}
// Explore neighbors and update distances
for (const [neighbor, weight] of adj[curr]) {
const newDist = currDist + weight;
if (newDist < distance[neighbor]) {
distance[neighbor] = newDist;
pq.push([newDist, neighbor]);
}
}
}
return distance;
}
function solve(n, m, edges) {
// Adjacency list for edges
const adj = Array.from({ length: n + 1 }, () => []);
// Build the adjacency list for edges
for (const [x, y, z] of edges) {
adj[x].push([y, z]);
adj[y].push([x, z]);
}
// Compute minimum distances from vertex 1 and vertex N
const dis1 = dijkstra(n, m, adj, 1);
const dis2 = dijkstra(n, m, adj, n);
let ans = Number.MAX_SAFE_INTEGER;
// Iterate through all edges to find the minimum cost of
// reducing an edge to 0
for (const [v, u, weight] of edges) {
// Calculate the cost of reducing edge (v, u) to 0
ans = Math.min(ans, dis1[v] + dis2[u], dis1[u] + dis2[v]);
}
// Output the minimum cost
console.log(ans);
}
const n = 4;
const m = 4;
// Edges as (vertex1, vertex2, weight)
const edges = [
[1, 2, 3],
[2, 3, 1],
[1, 3, 7],
[3, 4, 2]
];
// Call the solve function to find the answer
solve(n, m, edges);
Time Complexity: O(mlogn), m is number of edges and n is number of edges.
Auxiliary space: O(n+m),
Problem 2: You are given an undirected weighted graph with   N vertices. There are m1 edges which are of TYPE1 and m2 edges which are of TYPE2. The ith TYPE1 edge goes from vertex vi to vertex ui , and weight wi. The ith TYPE2 edge goes from vertex 1 to vertex vi , and weight wi. The task is to determine the maximum TYPE2 edges which can be removed such that the shortest path from vertex 1 to every other vertex remains the same. There can be multiple edges of same type between two vertices.
Let's see how we can apply Dijkstra's Algorithm to above problem:
Observation: The ith edge of TYPE 2 which goes from vertex 1 to vertex vi and has weight wi, can be removed if a there exist a path without using this edge such that total distance of this path is less than or equal to wi. We will first use all edges of TYPE 2, and update the dis[] array, dis[i] represents the shortest distance from vertex 1 to vertex ai and create vis[]
Applying Dijkstra's Algorithm: Choose a vertex v with the smallest value of dis[v] that is unmarked. Set vis[v] as true (mark it). Then iterate over all edges (v->u) , and if dis[v] + w <= dis[u], then we don't need any edges of TYPE 2 that goes from vertex 1 to vertex u since there exist a path without using the edges (1->u) such that total distance of this path is less than or equal to weight of any edge of TYPE 2 hat goes from vertex 1 to vertex u. We can set ans[u]=false, which indicates that we don't need any edges of TYPE 2 that goes from vertex 1 to vertex u.
Final answer: If ans[i]=true, then we need a edge of type 2 that goes from vertex 1 to vertex 1. Thus, we can determine at the end the number of vertices i for which ans[i]=true and store it in count.
Hence our final answer will be m2-count, where m2 is the number of edges of TYPE 2 and count is the number of edges of TYPE 2 which are required.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
// Function to solve the problem
void solve(int n, int m1, int m2,
vector<vector<int> >& edges1,
vector<vector<int> >& edges2)
{
// Adjacency list for TYPE 1 edges
vector<vector<pair<int, int> > > adj(n + 1);
// Array to mark which TYPE 2 edges are needed
vector<bool> ans(n + 1);
// Array to store the shortest distances
vector<int> dis(n + 1, INT_MAX);
// Build the adjacency list for TYPE 1 edges
for (int i = 0; i < m1; i++) {
int x = edges1[i][0], y = edges1[i][1],
z = edges1[i][2];
adj[x].push_back({ y, z });
adj[y].push_back({ x, z });
}
// Initialize dis[] and ans[] arrays for TYPE 2 edges
for (int i = 0; i < m2; i++) {
int x = edges2[i][0], y = edges2[i][1];
dis[x] = min(dis[x], y);
ans[x] = true;
}
set<pair<int, int> > pq;
dis[1] = 0;
pq.insert({ 0, 1 });
// Initialize the set with the distances
for (int i = 2; i <= n; i++) {
if (dis[i] != INT_MAX) {
pq.insert({ dis[i], i });
}
}
// Dijkstra's algorithm
while (!pq.empty()) {
int curr = (*pq.begin()).second;
int l = (*pq.begin()).first;
pq.erase(pq.begin());
for (auto x : adj[curr]) {
int d = x.first;
int len = x.second;
// Update the distance and ans[] if a shorter
// path is found
if (dis[d] >= len + dis[curr]) {
if (pq.find({ dis[d], d }) != pq.end()) {
pq.erase({ dis[d], d });
}
dis[d] = len + dis[curr];
pq.insert({ dis[d], d });
ans[d] = false;
}
}
}
int count = 0;
for (int i = 1; i <= n; i++) {
if (ans[i] == true) {
count++;
}
}
// Output the maximum number of TYPE 2 edges that can be
// removed
cout << m2 - count << "\n";
}
int main()
{
int n = 5, m1 = 5, m2 = 3;
// TYPE1 edges
vector<vector<int> > edges1 = { { 1, 2, 1 },
{ 2, 3, 2 },
{ 1, 3, 3 },
{ 3, 4, 4 },
{ 1, 5, 5 } };
// TYPE2 edges
vector<vector<int> > edges2
= { { 3, 5 }, { 4, 5 }, { 5, 5 } };
// Call the solve function to find the answer
solve(n, m1, m2, edges1, edges2);
}
Java
import java.util.*;
public class MaximumRemovableEdges {
// Function to solve the problem
static void solve(int n, int m1, int m2,
ArrayList<ArrayList<Integer> > edges1,
ArrayList<ArrayList<Integer> > edges2)
{
// Adjacency list for TYPE 1 edges
ArrayList<ArrayList<Pair> > adj
= new ArrayList<>(n + 1);
for (int i = 0; i <= n; i++) {
adj.add(new ArrayList<>());
}
// Array to mark which TYPE 2 edges are needed
boolean[] ans = new boolean[n + 1];
// Array to store the shortest distances
int[] dis = new int[n + 1];
Arrays.fill(dis, Integer.MAX_VALUE);
// Build the adjacency list for TYPE 1 edges
for (ArrayList<Integer> edge : edges1) {
int x = edge.get(0), y = edge.get(1),
z = edge.get(2);
adj.get(x).add(new Pair(y, z));
adj.get(y).add(new Pair(x, z));
}
// Initialize dis[] and ans[] arrays for TYPE 2
// edges
for (ArrayList<Integer> edge : edges2) {
int x = edge.get(0), y = edge.get(1);
dis[x] = Math.min(dis[x], y);
ans[x] = true;
}
TreeSet<Pair> pq = new TreeSet<>(
Comparator.comparingInt(o -> o.weight));
dis[1] = 0;
pq.add(new Pair(0, 1));
// Initialize the set with the distances
for (int i = 2; i <= n; i++) {
if (dis[i] != Integer.MAX_VALUE) {
pq.add(new Pair(dis[i], i));
}
}
// Dijkstra's algorithm
while (!pq.isEmpty()) {
Pair curr = pq.pollFirst();
int currVertex = curr.vertex;
int currDist = curr.weight;
for (Pair x : adj.get(currVertex)) {
int d = x.vertex;
int len = x.weight;
// Update the distance and ans[] if a
// shorter path is found
if (dis[d] >= len + dis[currVertex]) {
pq.remove(new Pair(dis[d], d));
dis[d] = len + dis[currVertex];
pq.add(new Pair(dis[d], d));
ans[d] = false;
}
}
}
int count = 0;
for (int i = 1; i <= n; i++) {
if (ans[i]) {
count++;
}
}
// Output the maximum number of TYPE 2 edges that
// can be removed
System.out.println(m2 - count);
}
public static void main(String[] args)
{
int n = 5, m1 = 5, m2 = 3;
// TYPE1 edges
ArrayList<ArrayList<Integer> > edges1
= new ArrayList<>(Arrays.asList(
new ArrayList<>(Arrays.asList(1, 2, 1)),
new ArrayList<>(Arrays.asList(2, 3, 2)),
new ArrayList<>(Arrays.asList(1, 3, 3)),
new ArrayList<>(Arrays.asList(3, 4, 4)),
new ArrayList<>(Arrays.asList(1, 5, 5))));
// TYPE2 edges
ArrayList<ArrayList<Integer> > edges2
= new ArrayList<>(Arrays.asList(
new ArrayList<>(Arrays.asList(3, 5)),
new ArrayList<>(Arrays.asList(4, 5)),
new ArrayList<>(Arrays.asList(5, 5))));
// Call the solve function to find the answer
solve(n, m1, m2, edges1, edges2);
}
static class Pair {
int weight;
int vertex;
Pair(int weight, int vertex)
{
this.weight = weight;
this.vertex = vertex;
}
}
}
Python
from heapq import heappush, heappop
# Function to solve the problem
def solve(n, m1, m2, edges1, edges2):
# Adjacency list for TYPE 1 edges
adj = [[] for _ in range(n + 1)]
# Array to mark which TYPE 2 edges are needed
ans = [False] * (n + 1)
# Array to store the shortest distances
dis = [float('inf')] * (n + 1)
# Build the adjacency list for TYPE 1 edges
for edge in edges1:
x, y, z = edge
adj[x].append((y, z))
adj[y].append((x, z))
# Initialize dis[] and ans[] arrays for TYPE 2 edges
for edge in edges2:
x, y = edge
dis[x] = min(dis[x], y)
ans[x] = True
pq = []
dis[1] = 0
heappush(pq, (0, 1))
# Dijkstra's algorithm
while pq:
l, curr = heappop(pq)
for x in adj[curr]:
d, length = x
# Update the distance and ans[] if a shorter path is found
if dis[d] >= length + dis[curr]:
dis[d] = length + dis[curr]
heappush(pq, (dis[d], d))
ans[d] = False
count = sum(1 for i in range(1, n + 1) if ans[i])
# Output the maximum number of TYPE 2 edges that can be removed
print(m2 - count)
# Main function
def main():
n = 5
m1 = 5
m2 = 3
# TYPE1 edges
edges1 = [[1, 2, 1],
[2, 3, 2],
[1, 3, 3],
[3, 4, 4],
[1, 5, 5]]
# TYPE2 edges
edges2 = [[3, 5], [4, 5], [5, 5]]
# Call the solve function to find the answer
solve(n, m1, m2, edges1, edges2)
if __name__ == "__main__":
main()
# this code is ocntributed by Prachi
JavaScript
// Function to solve the problem
function solve(n, m1, m2, edges1, edges2) {
// Adjacency list for TYPE 1 edges
let adj = Array.from({ length: n + 1 }, () => []);
// Array to mark which TYPE 2 edges are needed
let ans = Array(n + 1).fill(false);
// Array to store the shortest distances
let dis = Array(n + 1).fill(Number.MAX_SAFE_INTEGER);
// Build the adjacency list for TYPE 1 edges
for (let i = 0; i < m1; i++) {
let [x, y, z] = edges1[i];
adj[x].push([y, z]);
adj[y].push([x, z]);
}
// Initialize dis[] and ans[] arrays for TYPE 2 edges
for (let i = 0; i < m2; i++) {
let [x, y] = edges2[i];
dis[x] = Math.min(dis[x], y);
ans[x] = true;
}
let pq = new Set();
dis[1] = 0;
pq.add([0, 1]);
// Initialize the set with the distances
for (let i = 2; i <= n; i++) {
if (dis[i] !== Number.MAX_SAFE_INTEGER) {
pq.add([dis[i], i]);
}
}
// Dijkstra's algorithm
while (pq.size > 0) {
let curr = Array.from(pq)[0][1];
let l = Array.from(pq)[0][0];
pq.delete(Array.from(pq)[0]);
for (let [d, len] of adj[curr]) {
// Update the distance and ans[] if a shorter path is found
if (dis[d] >= len + dis[curr]) {
for (let entry of pq) {
if (entry[1] === d) {
pq.delete(entry);
break;
}
}
dis[d] = len + dis[curr];
pq.add([dis[d], d]);
ans[d] = false;
}
}
}
let count = 0;
for (let i = 1; i <= n; i++) {
if (ans[i] === true) {
count++;
}
}
// Output the maximum number of TYPE 2 edges that can be removed
console.log(m2 - count);
}
// Main function
function main() {
let n = 5, m1 = 5, m2 = 3;
// TYPE1 edges
let edges1 = [[1, 2, 1],
[2, 3, 2],
[1, 3, 3],
[3, 4, 4],
[1, 5, 5]];
// TYPE2 edges
let edges2 = [[3, 5], [4, 5], [5, 5]];
// Call the solve function to find the answer
solve(n, m1, m2, edges1, edges2);
}
// Call the main function
main();
//This code is contributed by Kishan.
Time Complexity: O(mlogn), m is number of edges of TYPE1.
Auxiliary space: O(n+m),
Practice Problems on Dijkstra's Algorithm for Competitive Programming: