Skip to content
Work Practice Products Coding interviews Machine learning coding Quant developer HFT course Blog Method Why me About Enquire Book a call

Coding · Graphs

Shortest paths by Dijkstra: beyond plain distances

Lesson · 10 min read · Graphs · Pattern: shortest path by Dijkstra

Dijkstra works for any cost that never decreases along a path: sums, maximums, waiting times. Recognising the cost is the whole problem.

What the pattern is

Dijkstra's algorithm needs one property: extending a path never makes its cost smaller. Ordinary sums of non-negative weights have it, but so do other costs:

  • The largest step on the path ("minimum effort": the biggest height difference along the route). The cost of a path is max(cost so far, next step), which never goes down.
  • The time you can start ("swim in rising water": you can enter a cell once the water reaches its height). The cost is max(time so far, height of the next cell).
  • Sums with state: cost per (node, stops used) for "at most k stops", or per (cell, fuel left).

With such a cost, the unsettled state with the smallest cost is final, exactly as in the ordinary algorithm. Only the combine step changes.

Generalised Dijkstra

best(start)

  1. Push (cost of start, start) into a min-heap.
  2. Pop the cheapest state; skip it if already settled; settle it; return its cost if it is the goal.
  3. For each move to a neighbour: newCost = combine(cost, move). Push it if it improves the neighbour.

How to recognise it

  • "Minimum cost", "least time", "minimum effort", "lowest maximum", "earliest time you can reach".
  • Moves have different costs, so plain breadth-first search is wrong.
  • The cost of extending a path never decreases. If it can (negative weights), use Bellman–Ford.
012012122382535
Heights on a grid. Down the left side and along the bottom, no single step changes height by more than 2, and no route does better. Any route through the 8 needs a step of at least 5.

Minimax problems also have a second solution: binary search on the answer, checking reachability with a search that only uses steps within the limit. Dijkstra is usually shorter to write.

TimeO(E log V)
SpaceO(V)

On a grid, V = rows · cols and E ≈ 4V.

The problems in this module: