Given a weighted directed acyclic graph (DAG) with V vertices (0 .. V-1) and edges edges[i] = [u, v, w] (a directed edge u → v of weight w), return an array dist where dist[i] is the shortest distance from source vertex 0 to vertex i, or -1 if i is unreachable.
Input: V = 4, edges = [[0,1,2],[0,2,4],[1,2,1],[2,3,3]] Output: [0, 2, 3, 6] 0→1→2→3 gives distances 0,2,3,6 (the 0→2 direct edge of 4 is beaten by 0→1→2 = 3).
Input: V = 4, edges = [[0,1,1],[2,3,1]] Output: [0, 1, -1, -1] Vertices 2 and 3 are unreachable from 0.
- 1 <= V <= 10^5 - 0 <= edges.length <= 10^5 - the graph is a DAG - edges are [u, v, w] directed
On a DAG you don't need Dijkstra or its heap — the acyclicity gives you a topological order in which every vertex's shortest distance is finalised before you process it. So: topologically sort, then walk the vertices in that order and relax each one's outgoing edges (dist[v] = min(dist[v], dist[u] + w)). One pass, O(V + E), and it works even with negative edge weights (no cycles means no negative loops).
The brute alternative is Bellman-Ford — relax all edges V-1 times — which also handles the DAG (indeed any graph without negative cycles) but at O(V·E).
“What's the source?”
Vertex 0.
“Unreachable vertices?”
Report -1.
Because it's a DAG I topologically sort, then relax edges in that order so each vertex is finalised once.
That's O(V+E) — no heap needed — and it even tolerates negative weights.
Worked example — V = 4, edges [[0,1,2],[0,2,4],[1,2,1],[2,3,3]]
topo order 0,1,2,3 0: dist[1]=2, dist[2]=4 1: dist[2]=min(4, 2+1)=3 2: dist[3]=3+3=6 dist = [0, 2, 3, 6]
Each vertex's shortest distance is set before it's processed.
Order replaces Dijkstra's priority queue on a DAG.
No cycles ⇒ no negative loops.
| Bellman-Ford | Topological relaxation | |
|---|---|---|
| Idea | relax all edges V-1 times | relax edges in topological order once |
| Time | O(V·E) | O(V+E) |
| Needs DAG |
Both give the same distances; the topological pass is linear. Full code is in the Approaches selector below.
Key takeaway
Topologically sort the DAG, then relax each vertex's outgoing edges in that order — every distance is finalised in one O(V+E) pass, even with negative weights.
order = toposort(V, edges) dist[0]=0; for u in order: for (u->v,w): dist[v] = min(dist[v], dist[u]+w)