Problem Overview
You are given an undirected weighted graph with V vertices and a list of edges. Each edge represents the time required to travel between two nodes.
The goal is:
Core Concept
This problem is an extension of the classic Dijkstra’s Algorithm.
Normally, Dijkstra helps us find:
But here, we also need:
Key Idea
We maintain two arrays:
dist[]
ways[]
Algorithm Strategy
Step 1: Build Graph
Step 2: Initialize
Step 3: Apply Dijkstra (Min Heap)
Step 4: Relaxation Logic (Important)
For every adjacent node:
Case 1: Shorter Path Found
if (newDist < dist[adjNode])
Update shortest distance
Copy number of ways
Why copy?
Case 2: Another Shortest Path Found
else if (newDist == dist[adjNode])
Why add?
Visualization (Simple Example)
0 ----(5)----> 3
\
(2)
\
1 ----(3)----> 3
Shortest time to reach node 3 = 5
Paths:
Total ways = 2
Complexity Analysis
| Type | Complexity |
|---|
| Time | O(E log V) |
| Space | O(V + E) |
Java Implementation
import java.util.*;
class Solution {
public int countPaths(int V, int[][] edges) {
final int MOD = 1_000_000_007;
// Step 1: Build graph
List<List<int[]>> graph = new ArrayList<>();
for (int i = 0; i < V; i++) {
graph.add(new ArrayList<>());
}
for (int[] e : edges) {
int u = e[0], v = e[1], w = e[2];
graph.get(u).add(new int[]{v, w});
graph.get(v).add(new int[]{u, w});
}
// Step 2: Distance & ways
long[] dist = new long[V];
long[] ways = new long[V];
Arrays.fill(dist, Long.MAX_VALUE);
dist[0] = 0;
ways[0] = 1;
// Step 3: Min Heap
PriorityQueue<long[]> pq = new PriorityQueue<>(
(a, b) -> Long.compare(a[0], b[0])
);
pq.offer(new long[]{0, 0}); // {distance, node}
while (!pq.isEmpty()) {
long[] curr = pq.poll();
long d = curr[0];
int node = (int) curr[1];
if (d > dist[node]) continue;
for (int[] neighbor : graph.get(node)) {
int adjNode = neighbor[0];
int weight = neighbor[1];
long newDist = d + weight;
if (newDist < dist[adjNode]) {
dist[adjNode] = newDist;
ways[adjNode] = ways[node];
pq.offer(new long[]{newDist, adjNode});
}
else if (newDist == dist[adjNode]) {
ways[adjNode] = (ways[adjNode] + ways[node]) % MOD;
}
}
}
return (int)(ways[V - 1] % MOD);
}
}
Summary
This problem extends Dijkstra’s Algorithm by not only computing the shortest distance but also tracking the number of shortest paths to each node. By maintaining both distance and ways arrays and carefully updating them during relaxation, we can efficiently determine how many minimum-time paths exist from the source to the destination with a time complexity of O(E log V).