Ý tưởng: Từ đỉnh nguồn, luôn mở rộng đỉnh có khoảng cách nhỏ nhất chưa chốt. Dùng min-heap (priority queue) để mỗi lần lấy ra đỉnh gần nhất trong O(log V), thay vì quét tuyến tính O(V).
Vì sao không có cạnh âm: Dijkstra giả định khi một đỉnh được pop ra khỏi heap thì khoảng cách của nó đã tối ưu, vĩnh viễn không nhỏ hơn được nữa. Cạnh âm phá vỡ giả định đó (một đường vòng có thể rẻ hơn về sau) → dùng Bellman-Ford.
ts
function networkDelayTime(times: number[][], n: number, k: number): number {
const adj: [number, number][][] = Array.from({ length: n + 1 }, () => [])
for (const [u, v, w] of times) adj[u].push([v, w])
const dist = new Array(n + 1).fill(Infinity)
dist[k] = 0
const heap: [number, number][] = [[0, k]] // [khoảng cách, đỉnh]
while (heap.length) {
heap.sort((a, b) => a[0] - b[0]) // thực tế dùng binary heap
const [d, u] = heap.shift()!
if (d > dist[u]) continue
for (const [v, w] of adj[u])
if (d + w < dist[v]) { dist[v] = d + w; heap.push([dist[v], v]) }
}
const ans = Math.max(...dist.slice(1))
return ans === Infinity ? -1 : ans
}Độ phức tạp: O(E log V) với binary heap; bộ nhớ O(V+E).
Lưu ý: Bỏ qua entry cũ bằng if (d > dist[u]) continue để khỏi xử lý lại — đây là điểm hay quên gây TLE.