Skip to main content

Dijkstra Algorithm

Problem Statement:​

Given an undirected, weighted graph with V vertices numbered from 0 to V-1 and E edges, represented by 2d array edges[][], where edges[i]=[u, v, w] represents the edge between the nodes u and v having w edge weight.You have to find the shortest distance of all the vertices from the source vertex src, and return an array of integers where the ith element denotes the shortest distance between ith node and source vertex src.

Note: The Graph is connected and doesn't contain any negative weight edge.

Examples:

Input:V = 3, edges[][] = [[0, 1, 1], [1, 2, 3], [0, 2, 6]], src = 2
Output:[4, 3, 0]
Explanation:

Shortest Paths:
For 2 to 0 minimum distance will be 4. By following path 2 -> 1 -> 0
For 2 to 1 minimum distance will be 3. By following path 2 -> 1
For 2 to 2 minimum distance will be 0. By following path 2 -> 2

Input:V = 5, edges[][] = [[0, 1, 4], [0, 2, 8], [1, 4, 6], [2, 3, 2], [3, 4, 10]], src = 0
Output:[0, 4, 8, 10, 10]
Explanation:

Shortest Paths:
For 0 to 1 minimum distance will be 4. By following path 0 -> 1
For 0 to 2 minimum distance will be 8. By following path 0 -> 2
For 0 to 3 minimum distance will be 10. By following path 0 -> 2 -> 3
For 0 to 4 minimum distance will be 10. By following path 0 -> 1 -> 4

  • Example:


✅ Solution: Dijkstra’s Algorithm Using Set vs. Priority Queue (Side-by-Side Comparison)​


✅ Solution 1: Dijkstra Using set (With Erase-Update)​

class Solution {
public:
vector<int> dijkstraSet(int V, vector<vector<int>> &edges, int src) {
vector<vector<pair<int, int>>> adjList(V);

for (auto it : edges) {
adjList[it[0]].push_back({it[1], it[2]});
adjList[it[1]].push_back({it[0], it[2]});
}

set<pair<int, int>> st; // {distance, node}
st.insert({0, src});

vector<int> dist(V, 1e9);
dist[src] = 0;

while (!st.empty()) {
auto it = *(st.begin());
st.erase(it);

int node = it.second;
int dis = it.first;

for (auto neighbor : adjList[node]) {
int neigh = neighbor.first;
int edgeW = neighbor.second;

if (dist[neigh] > dist[node] + edgeW) {
if (dist[neigh] != 1e9) {
st.erase({dist[neigh], neigh});
}
dist[neigh] = dist[node] + edgeW;
st.insert({dist[neigh], neigh});
}
}
}

return dist;
}
};


✅ Solution 2: Dijkstra Using priority_queue (Lazy Deletion)​

class Solution {
public:
vector<int> dijkstraPQ(int V, vector<vector<int>> &edges, int src) {
vector<vector<pair<int, int>>> adjList(V);

for (auto it : edges) {
adjList[it[0]].push_back({it[1], it[2]});
adjList[it[1]].push_back({it[0], it[2]});
}

priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push({0, src});

vector<int> dist(V, 1e9);
dist[src] = 0;

while (!pq.empty()) {
auto it = pq.top();
pq.pop();

int node = it.second;
int dis = it.first;

if (dis > dist[node]) continue; // Skip outdated entry

for (auto neighbor : adjList[node]) {
int neigh = neighbor.first;
int edgeW = neighbor.second;

if (dist[neigh] > dist[node] + edgeW) {
dist[neigh] = dist[node] + edgeW;
pq.push({dist[neigh], neigh});
}
}
}

return dist;
}
};


📝 How Both Versions Work​

  • Common Setup: Build an adjacency list with {neighbor, weight} pairs.
  • Core Logic: Relax edges using the smallest distance available at each step.

✅ Set Version Notes:​

  • Only keeps the latest {distance, node}.
  • Needs manual erase before insert if a better path is found.
  • Ensures no outdated entries exist in the set.

✅ Priority Queue Version Notes:​

  • Can’t erase elements. Keeps old values.
  • Uses lazy deletion:
    • If a popped node’s distance is already better (if (dis > dist[node])), skip processing it.

🧩 Key Formula​

  • Relaxation Formula:

    if (dist[neigh] > dist[node] + weight):
    dist[neigh] = dist[node] + weight


⏱️ Time & Space Complexity Comparison​

ApproachTime ComplexitySpace Complexity
SetO((V + E) * log V)O(V + E)
Priority QueueO((V + E) * log V)O(V + E)
  • Set is slower in practice due to erase() overhead.
  • Priority queue is preferred for contests and production code because of simpler logic.

⚠️ Edge Cases​

  • Disconnected graph → Some nodes retain initial 1e9 value.
  • Multiple edges → Only the shortest path is retained.

💡 Other Approaches​

ApproachTime ComplexityNotes
Bellman-FordO(V * E)Handles negative weights.
Floyd-WarshallO(V³)All-pairs shortest paths.

  • LeetCode 743: Network Delay Time
  • GFG: Dijkstra’s Algorithm (Set + Priority Queue versions)
  • LeetCode 787: Cheapest Flights Within K Stops

🛠️ Other Notes (Optional)​

  • ✅ Set is good for theoretical understanding (true decrease-key behavior).
  • ✅ Priority Queue is more common and practical.
  • ✅ Real-world analogy: Like updating your map app’s route list with quicker paths as new traffic data comes in, either by updating entries or just ignoring outdated suggestions.
🚀 Level Up Your Engineering Mindset

Never Study in Isolation. Join Binary Dose.

Connect with fellow engineers, clear conceptual doubts, and get 2 visual breakdowns & engineering mental models daily across our community channels.

Discord
Official Hub

Discord Community

Start at #welcome-and-rules, say hello in #general-chat, clear doubts, and collaborate with engineers worldwide.

Join Discord Server→
⚡
Daily Knowledge Drops

Daily Visual Deep-Dives

Bite-sized system design schematics, core OS internals, and DSA intuition served right into your feeds every single day.

💡Have handwritten notes, cheat-sheets, or want to publish a technical article?
Learn How to Contribute→