On a DAG, shortest paths are a linear-time DP — no priority queue, no relaxation rounds, and negative weights are perfectly fine. Always check whether your graph is acyclic before reaching for Dijkstra.

SSSP in

Process vertices in topological order and relax outgoing edges. Once a vertex is reached in topological order, no future vertex can improve it, because every path into it comes from earlier vertices.

vector<long long> ssspDAG(int n, vector<vector<pair<int,long long>>>& adj, int s) {
    vector<int> order = topoOrder(n, adj);            // Kahn or DFS
    const long long INF = LLONG_MAX / 4;
    vector<long long> dist(n, INF);
    dist[s] = 0;
    for (int u : order) {
        if (dist[u] == INF) continue;
        for (auto [v, w] : adj[u])
            dist[v] = min(dist[v], dist[u] + w);
    }
    return dist;
}

Longest path in

Longest path is NP-hard on general graphs. On a DAG it is the same loop with max, or equivalently: negate every weight, run SSSP, negate the answers back.

for (int u : order) {
    if (dp[u] == NEG_INF) continue;
    for (auto [v, w] : adj[u]) dp[v] = max(dp[v], dp[u] + w);
}

This is the standard solution to critical path / project scheduling (PERT): the longest path through a task DAG is the minimum possible completion time.

Why this beats everything else

AlgorithmTimeNegative weightsNeeds a DAG
BFSno (unweighted only)no
Topological DPyesyes
Dijkstranono
Bellman-Fordyesno
Floyd-Warshallyesno

Other DAG DPs, all the same loop

Once you have a topological order, every one of these is one pass:

QuestionRecurrence
Number of paths
Longest path ending at
Number of shortest pathscarry a count alongside the distance, reset on improvement
Reachable set from process in reverse topological order, union the successors’ sets (bitset)
Minimum path cover of a DAG minus the maximum bipartite matching of the split graph (Dilworth)
Longest common subsequence, edit distance, grid pathsthese are DAG DPs — the grid is the DAG

Every DP is a DAG shortest path

A DP’s states and transitions form a DAG; “compute in an order where dependencies come first” is exactly topological order. Recognising this makes it obvious why a DP with a cyclic dependency needs Dijkstra or Bellman-Ford instead of a plain loop. See DP on DAGs.

Hidden DAGs

Some graphs are DAGs only after a transformation:

  • Condensation. Contract the SCCs of any directed graph and the result is a DAG. Longest path in the condensation, weighted by component size, answers “largest set of mutually reachable vertices along a path”.
  • Layered graphs. If state includes “steps used so far” and steps only increase, the state graph is a DAG even when the underlying graph has cycles.
  • Grids with monotone movement. Only right/down moves means the grid is a DAG.

See also: Topological Sort · DP on DAGs · Shortest Paths