---
Difficulty: Medium
Source: 160 Days of Problem Solving
Tags:
- Graph
---
# 🚀 _Day 11. Dijkstra’s Algorithm_ 🧠
The problem can be found at the following link: [Question Link](https://www.geeksforgeeks.org/batch/gfg-160-problems/track/graph-gfg-160/problem/implementing-dijkstra-set-1-adjacency-matrix)
## 💡 **Problem Description:**
Given an **undirected, weighted graph** with **V** vertices numbered from **0** to **V-1** and **E** edges, represented by a 2D array `edges[][]` (where each `edges[i] = [u, v, w]` represents an edge between nodes **u** and **v** with weight **w**), find the shortest distance from a given source vertex **src** to all other vertices.
Return an array of integers where the _ith_ element denotes the shortest distance from the source vertex **src** to vertex **i**.
> **Note:** The graph is connected and does not contain any negative weight edge.
> **Note:** Sorry for uploading late, my Final Sem exam is going on.
## 🔍 **Example Walkthrough:**
### **Example 1:**
#### **Input:**
```
V = 3
edges[][] = [[0, 1, 1], [1, 2, 3], [0, 2, 6]]
src = 2
```
#### **Output:**
```
[4, 3, 0]
```
#### **Explanation:**
- For vertex **0**: The shortest path is `2 -> 1 -> 0` with total distance **4**.
- For vertex **1**: The shortest path is `2 -> 1` with total distance **3**.
- For vertex **2**: The distance is **0** as it is the source.
### **Example 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:**
- For vertex **1**: The shortest path is `0 -> 1` with total distance **4**.
- For vertex **2**: The shortest path is `0 -> 2` with total distance **8**.
- For vertex **3**: The shortest path is `0 -> 2 -> 3` with total distance **10**.
- For vertex **4**: The shortest path is `0 -> 1 -> 4` with total distance **10**.
### **🔐 Constraints**
- $1 \leq V \leq 10^4$
- $1 ≤ E = edges.size() ≤ 10^5$
- $0 ≤ edges[i][j] ≤ 10^4$
- $0 \leq src < V$
- Edge weights are non-negative
## 🎯 **My Approach:**
### **Optimized Dijkstra’s Algorithm (Min-Heap + Adjacency List)**
1. **Build the Graph:** Convert the given edge list into an adjacency list representation.
2. **Initialize Distances:** Set a distance vector `d[]` with high values and update `d[src] = 0`.
3. **Min-Heap (Priority Queue):** Use a min-heap to pick the node with the smallest tentative distance.
4. **Relaxation:** For each neighboring vertex, update its distance if a shorter path is found.
### **Algorithm Steps:**
1. Convert the edges into an adjacency list `g`.
2. Initialize a distance array `d` of size **V** with a large value (e.g., `1e9`), and set `d[src] = 0`.
3. Push `(0, src)` into a min-heap.
4. While the heap is not empty:
- Pop the top element (with the smallest tentative distance).
- If the current distance is greater than the recorded distance, continue to the next.
- Otherwise, for each adjacent vertex, check if the path through the current vertex gives a smaller distance; update and push the new pair in the heap.
5. Return the distance array `d` as the result.
## 🕒 **Time and Auxiliary Space Complexity**
- **Expected Time Complexity:** O((V + E) \* log V), since each vertex and edge is processed, and insertion/extraction from the heap takes logarithmic time.
- **Expected Auxiliary Space Complexity:** O(V + E), for the adjacency list and the additional storage used by the heap.
## 📝 **Solution Code**
## **Code (C++)**
```cpp
// ✅ Optimized Dijkstra’s Algorithm (Min-Heap + Adjacency List)
class Solution {
public:
vector dijkstra(int V, vector> &edges, int src) {
vector>> g(V);
for (auto &e : edges) g[e[0]].emplace_back(e[1], e[2]);
vector d(V, 1e9); d[src] = 0;
priority_queue, vector>, greater<>> q;
q.emplace(0, src);
while (!q.empty()) {
auto p = q.top(); q.pop();
if (p.first > d[p.second]) continue;
for (auto &x : g[p.second])
if (p.first + x.second < d[x.first])
q.emplace(d[x.first] = p.first + x.second, x.first);
}
return d;
}
};
```
⚡ Alternative Approaches
## 📊 **2️⃣ Dijkstra using Set instead of Min-Heap**
#### **Algorithm Steps:**
1. Build an adjacency list `g` from the edges.
2. Initialize distance array `d` with large values, and set `d[src] = 0`.
3. Use a `std::set` to mimic a min-priority queue, which maintains sorted order automatically.
4. At each step, pick the node with the smallest tentative distance.
5. For each adjacent node, if a shorter path is found, update and insert the new pair.
```cpp
class Solution {
public:
vector dijkstra(int V, vector> &edges, int src) {
vector>> g(V);
for (auto &e : edges) g[e[0]].emplace_back(e[1], e[2]);
vector d(V, 1e9);
d[src] = 0;
set> st;
st.emplace(0, src);
while (!st.empty()) {
pair p = *st.begin();
int du = p.first;
int u = p.second;
st.erase(st.begin());
for (int i = 0; i < g[u].size(); ++i) {
int v = g[u][i].first;
int w = g[u][i].second;
if (du + w < d[v]) {
st.erase({d[v], v});
d[v] = du + w;
st.emplace(d[v], v);
}
}
}
return d;
}
};
```
#### 📝 **Complexity Analysis:**
- **Expected Time Complexity:** O((V + E) \* log V)
- **Expected Auxiliary Space Complexity:** O(V + E)
#### ✅ **Why This Approach?**
- Leverages `std::set` to ease decrease-key operations.
- Provides more control over updates at the cost of increased insertion/erase overhead compared to the min-heap.
### 🆚 **Comparison of Approaches**
| **Approach** | ⏱️ **Time Complexity** | 🗂️ **Space Complexity** | ✅ **Pros** | ⚠️ **Cons** |
| ----------------------------- | ---------------------- | ----------------------- | ----------------------------------------------- | ------------------------------------------- |
| **Min-Heap (Priority Queue)** | 🟢 O((V + E) \* log V) | 🟡 O(V + E) | Fast for sparse graphs, standard implementation | Slightly verbose STL usage |
| **Set-Based Approach** | 🟡 O((V + E) \* log V) | 🟡 O(V + E) | Easy key updates using ordered set | Set operations can be slower than heap push |
✅ **Best Choice?**
- **Min-Heap (Priority Queue):** Best for most competitive and real-world graph problems.
- **Set-Based Approach:** Use when you require more explicit key updates.
## **Code (Java)**
```java
class Solution {
public int[] dijkstra(int V, int[][] edges, int src) {
List[] g = new List[V];
for (int i = 0; i < V; i++) g[i] = new ArrayList<>();
for (int[] e : edges) g[e[0]].add(new int[]{e[1], e[2]});
int[] d = new int[V];
Arrays.fill(d, Integer.MAX_VALUE);
d[src] = 0;
PriorityQueue q = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
q.offer(new int[]{0, src});
while (!q.isEmpty()) {
int[] p = q.poll();
if (p[0] > d[p[1]]) continue;
for (int[] x : g[p[1]])
if (p[0] + x[1] < d[x[0]])
q.offer(new int[]{d[x[0]] = p[0] + x[1], x[0]});
}
return d;
}
}
```
## **Code (Python)**
```python
class Solution:
def dijkstra(self, V, edges, src):
from heapq import heappush, heappop
g = [[] for _ in range(V)]
for u, v, w in edges:
g[u].append((v, w))
d = [float('inf')] * V
d[src] = 0
q = [(0, src)]
while q:
du, u = heappop(q)
if du > d[u]: continue
for v, w in g[u]:
if du + w < d[v]:
d[v] = du + w
heappush(q, (d[v], v))
return d
```
## 🎯 **Contribution and Support:**
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: [Any Questions](https://www.linkedin.com/in/patel-hetkumar-sandipbhai-8b110525a/). Let’s make this learning journey more collaborative!
⭐ **If you find this helpful, please give this repository a star!** ⭐
---
📍Visitor Count