// adj: Array of arrays of {to, w}; 0-indexed nodes
function dijkstra(adj, s) {
const n = adj.length;
const dist = Array(n).fill(Infinity);
const parent = Array(n).fill(-1);
dist[s] = 0;
// Simple binary heap implementation
const heap = [];
const push = (x) => { heap.push(x); up(heap.length - 1); };
const up = (i) => { while (i) { const p = (i - 1) >> 1; if (heap[p][0] <= heap[i][0]) break; [heap[p], heap[i]] = [heap[i], heap[p]]; i = p; } };
const down = (i) => { for (;;) { let l = i*2+1, r = l+1, m = i; if (l < heap.length && heap[l][0] < heap[m][0]) m = l; if (r < heap.length && heap[r][0] < heap[m][0]) m = r; if (m === i) break; [heap[m], heap[i]] = [heap[i], heap[m]]; i = m; } };
const pop = () => { const top = heap[0]; const last = heap.pop(); if (heap.length) { heap[0] = last; down(0); } return top; };
push([0, s]);
while (heap.length) {
const [d, u] = pop();
if (d !== dist[u]) continue; // stale
for (const {to: v, w} of adj[u]) {
const nd = d + w;
if (nd < dist[v]) { dist[v] = nd; parent[v] = u; push([nd, v]); }
}
}
return { dist, parent };
}
function reconstructPath(parent, t) {
const path = [];
for (let v = t; v !== -1; v = parent[v]) path.push(v);
return path.reverse();
}
- Complexity: O((n + m) log n) with binary heap; O(m + n log n) commonly.
- Non-negative weights only: otherwise correctness fails.