Dijkstra's Algorithm Single Source Shortest Path in DSA C# - Time & Space Complexity
We want to understand how the time needed to find shortest paths grows as the graph gets bigger.
How does the algorithm's work increase when there are more nodes and edges?
Analyze the time complexity of the following code snippet.
// Simplified Dijkstra's Algorithm using adjacency list and priority queue
int V = graph.Length; // number of vertices
int[] dist = new int[V];
for (int i = 0; i < V; i++) dist[i] = int.MaxValue;
dist[source] = 0;
var pq = new PriorityQueue<int, int>();
pq.Enqueue(source, 0);
while (pq.Count > 0) {
var u = pq.Dequeue();
foreach (var (v, w) in graph[u]) {
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
pq.Enqueue(v, dist[v]);
}
}
}
This code finds the shortest distance from one node to all others using a priority queue and adjacency list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop runs as long as there are nodes in the priority queue.
- How many times: Each edge is checked at most once when relaxing distances, so roughly once per edge.
- Inside the while loop, the foreach loop goes through all neighbors of the current node.
- Priority queue operations (enqueue and dequeue) happen for nodes when their distances improve.
As the number of nodes (V) and edges (E) grow, the operations increase based on how many edges and nodes are processed.
| Input Size (V, E) | Approx. Operations |
|---|---|
| 10 nodes, 20 edges | About 20 edge checks and 10 node queue operations |
| 100 nodes, 500 edges | About 500 edge checks and 100 node queue operations |
| 1000 nodes, 5000 edges | About 5000 edge checks and 1000 node queue operations |
Pattern observation: The work grows roughly with the number of edges and nodes combined, not just nodes alone.
Time Complexity: O((V + E) log V)
This means the time grows with the number of nodes plus edges, multiplied by the cost of priority queue operations.
[X] Wrong: "Dijkstra's algorithm always runs in O(V²) time regardless of data structures."
[OK] Correct: Using a priority queue and adjacency list reduces the time to O((V + E) log V), which is much faster especially for sparse graphs.
Understanding this time complexity helps you explain how your solution scales and why choosing the right data structures matters.
"What if we used a simple array instead of a priority queue? How would the time complexity change?"
Practice
Solution
Step 1: Understand the goal of Dijkstra's Algorithm
Dijkstra's Algorithm is designed to find the shortest paths from one starting point (source) to all other points in a weighted graph.Step 2: Compare with other graph algorithms
Minimum spanning tree algorithms find a tree connecting all vertices with minimum total edge weight, cycle detection finds loops, and topological sort orders vertices in a DAG. These are different goals.Final Answer:
To find the shortest path from a single source to all other vertices -> Option BQuick Check:
Dijkstra's Algorithm = shortest path from source [OK]
- Confusing shortest path with minimum spanning tree
- Thinking it detects cycles
- Mixing it with topological sorting
Solution
Step 1: Understand initialization for Dijkstra's distances
Distances are set to a very large number (infinity) initially, except the source vertex which is set to 0 later.Step 2: Check each option
int[] dist = new int[5]; for(int i = 0; i < 5; i++) dist[i] = int.MaxValue; sets all distances to int.MaxValue, which is correct. int[] dist = new int[5] {0, 0, 0, 0, 0}; sets all to 0, which is wrong. int[] dist = new int[5]; dist.Fill(0); uses a non-existent Fill method. int[] dist = new int[5]; for(int i = 0; i < 5; i++) dist[i] = -1; sets distances to -1, which is invalid for distances.Final Answer:
int[] dist = new int[5]; for(int i = 0; i < 5; i++) dist[i] = int.MaxValue; -> Option DQuick Check:
Initialize distances to max value [OK]
- Setting all distances to zero initially
- Using negative values for distances
- Using non-existent array methods
int[,] graph = {
{0, 1, 4, 0},
{1, 0, 2, 6},
{4, 2, 0, 3},
{0, 6, 3, 0}
};
int V = 4;
int[] dist = new int[V];
bool[] sptSet = new bool[V];
for (int i = 0; i < V; i++) dist[i] = int.MaxValue;
dist[0] = 0;
for (int count = 0; count < V - 1; count++) {
int u = -1;
int minDist = int.MaxValue;
for (int v = 0; v < V; v++) {
if (!sptSet[v] && dist[v] < minDist) {
minDist = dist[v];
u = v;
}
}
sptSet[u] = true;
for (int v = 0; v < V; v++) {
if (!sptSet[v] && graph[u, v] != 0 && dist[u] != int.MaxValue && dist[u] + graph[u, v] < dist[v]) {
dist[v] = dist[u] + graph[u, v];
}
}
}
Console.WriteLine(dist[3]);Solution
Step 1: Trace the algorithm's distance updates
Start dist = [0, ∞, ∞, ∞]. - Pick vertex 0: update dist[1] = 1, dist[2] = 4. - Pick vertex 1 (dist=1): update dist[2] = min(4, 1+2=3) = 3, dist[3] = 1+6=7. - Pick vertex 2 (dist=3): update dist[3] = min(7, 3+3=6) = 6. - Pick vertex 3 (dist=6): done.Step 2: Final shortest distance to vertex 3
After all updates, dist[3] = 6.Final Answer:
6 -> Option AQuick Check:
Shortest distance to vertex 3 = 6 [OK]
- Not updating distances when a shorter path is found
- Confusing vertex indices
- Ignoring zero-weight edges as no edge
int V = 3;
int[] dist = new int[V];
bool[] visited = new bool[V];
for (int i = 0; i < V; i++)
dist[i] = int.MaxValue;
dist[0] = 0;
for (int count = 0; count < V; count++) {
int u = 0;
for (int v = 0; v < V; v++) {
if (!visited[v] && dist[v] < dist[u])
u = v;
}
visited[u] = true;
// Update distances here (omitted)
}Solution
Step 1: Analyze initialization of u in inner loop
Variable u is set to 0 before checking for minimum dist among unvisited vertices. If dist[0] is int.MaxValue, comparison fails and minimum may not be found correctly.Step 2: Correct approach for minimum selection
u should be initialized to -1 or a sentinel, and updated only when a better candidate is found to avoid wrong minimum selection.Final Answer:
Variable u is initialized to 0 causing incorrect minimum selection -> Option AQuick Check:
Initialize u properly to find minimum dist [OK]
- Initializing min index to 0 without checking if visited
- Not updating visited array
- Incorrect loop count
0 -> 1 (2), 0 -> 2 (4), 1 -> 2 (1), 1 -> 3 (7), 2 -> 4 (3), 3 -> 4 (1)Using Dijkstra's Algorithm from vertex 0, what is the shortest path distance to vertex 4?
Solution
Step 1: Trace shortest paths from vertex 0
Start dist = [0, ∞, ∞, ∞, ∞]. - From 0: dist[1] = 2, dist[2] = 4. - From 1: dist[2] = min(4, 2+1=3) = 3, dist[3] = 2+7=9. - From 2: dist[4] = 3+3=6. - From 3: dist[4] = min(6, 9+1=10) = 6.Step 2: Final shortest distance to vertex 4
The shortest distance to vertex 4 is 6 via path 0->1->2->4.Final Answer:
6 -> Option CQuick Check:
Shortest path distance to 4 = 6 [OK]
- Ignoring shorter indirect paths
- Adding edge weights incorrectly
- Assuming direct edge is always shortest
Ready to prove it?
Pass the test and this pattern moves unknown
