Algorithm

int[] spfa(int src, List[] graph) {
  int[] dist = new int[graph.length];
  Arrays.fill(dist, Integer.MAX_VALUE);
  dist[src] = 0;
  boolean[] inQueue = new boolean[graph.length];
  Deque q = new ArrayDeque<>();
  q.offer(src); inQueue[src] = true;
  while (!q.isEmpty()) {
    int u = q.poll(); inQueue[u] = false;
    for (int[] edge : graph[u]) {
      int v = edge[0], w = edge[1];
      if (dist[u] + w < dist[v]) {
        dist[v] = dist[u] + w;
        if (!inQueue[v]) { q.offer(v); inQueue[v] = true; }
      }
    }
  }
  return dist;
}
Advertisement

SLF optimization

Smallest Label First: push to front if new dist < current head, back otherwise. Speeds up in practice.

Advertisement

LLL optimization

Large Label Last: skip head if it's above average; requeue at back. Combined with SLF.

Complexity

Average: O(kE) with small k. Worst case: O(VE) — same as Bellman-Ford. Sneaky inputs can force this.