When edges have lengths
BFS counts hops. But on a real map one road might be 2 km and another 50 km. For the shortest total distance we use Dijkstra's algorithm (all lengths must be zero or positive).
The idea
- Every place starts with distance “infinity”, except the start: 0.
- Pick the unfinished place with the smallest known distance – a PriorityQueue does this fast.
- Its distance is now final. Try every road out of it: if going through it makes a neighbour closer, update the neighbour and add it to the queue.
- Repeat until the queue is empty.
Think of it like this: Water spreading from a tap through pipes of different lengths: it reaches nearby joints first, and each joint is reached for the first time along the shortest pipe route.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
class ByDistance implements Comparator<long[]> {
public int compare(long[] a, long[] b) { return Long.compare(a[1], b[1]); }
}
public class Main {
public static void main(String[] args) {
int n = 5;
ArrayList<ArrayList<int[]>> g = new ArrayList<ArrayList<int[]>>(); // {neighbour, length}
for (int i = 0; i <= n; i++) g.add(new ArrayList<int[]>());
int[][] roads = {{1, 2, 4}, {1, 3, 1}, {3, 2, 2}, {2, 4, 5}, {3, 4, 8}, {4, 5, 3}};
for (int[] r : roads) {
g.get(r[0]).add(new int[]{r[1], r[2]});
g.get(r[1]).add(new int[]{r[0], r[2]});
}
long[] dist = new long[n + 1];
Arrays.fill(dist, Long.MAX_VALUE);
dist[1] = 0;
PriorityQueue<long[]> pq = new PriorityQueue<long[]>(new ByDistance()); // {place, distance}
pq.offer(new long[]{1, 0});
while (!pq.isEmpty()) {
long[] top = pq.poll();
int u = (int) top[0];
if (top[1] > dist[u]) continue; // an old, out-of-date entry: skip
for (int[] road : g.get(u)) {
int v = road[0];
if (dist[u] + road[1] < dist[v]) { // found a shorter way to v
dist[v] = dist[u] + road[1];
pq.offer(new long[]{v, dist[v]});
}
}
}
for (int place = 1; place <= n; place++) System.out.println("to " + place + ": " + dist[place] + " km");
}
}Output
to 1: 0 km to 2: 3 km to 3: 1 km to 4: 8 km to 5: 11 km
Notice place 2: the direct road is 4 km, but going 1 → 3 → 2 is only 3 km, and Dijkstra finds it. With a PriorityQueue the running time is O((n + m) log n).
Common mistake: Using Dijkstra with negative road lengths. It assumes a place is final once it's the closest – a negative road could make it closer later. (Other algorithms, like Bellman-Ford, handle that.)