Dijkstra — đường đi ngắn nhất một nguồn
Dijkstra tìm đường đi ngắn nhất từ một nguồn tới mọi đỉnh khác, khi các cạnh có trọng số không âm. BFS đếm số cạnh; Dijkstra cộng trọng số. Bí quyết tốc độ là một hàng đợi ưu tiên / heap luôn cho ra đỉnh gần nhất chưa chốt, đạt O(E log V).
1. Trực quan: luôn mở rộng đỉnh rẻ nhất
Hãy hình dung bạn đi từ nhà tới mọi địa điểm, mỗi đoạn đường tốn một số phút. Dijkstra theo nguyên tắc tham lam: trong số những nơi chưa chốt, luôn bước tới nơi có tổng thời gian nhỏ nhất trước. Vì cạnh không âm, một khi đã chốt một đỉnh thì khoảng cách của nó không thể tốt hơn nữa.
2 3
A ------- B ------- D
\ /
\ 6 1 /
\ /
---- C -----
Tu A:
dist[A]=0
dist[B]=2 (A->B)
dist[C]=6 (A->C)
dist[D]=5 (A->B->D = 2+3) re hon A->C->D = 6+1=7
2. Cơ chế: heap + bảng dist
| Thành phần | Vai trò |
|---|---|
dist[v] | khoảng cách ngắn nhất đã biết tới v (khởi tạo vô cực) |
| heap | cặp (khoang_cach, dinh), luôn lấy ra đỉnh nhỏ nhất |
| giãn cạnh (relax) | nếu dist[v] > dist[u] + w thì cập nhật dist[v] |
Vòng lặp: lấy đỉnh u rẻ nhất ra khỏi heap, thử giãn mọi cạnh đi ra của nó. Nếu tìm được đường
tốt hơn tới hàng xóm v, cập nhật và đẩy (dist_moi, v) vào heap.
Tính tham lam dựa trên giả định: đã lấy đỉnh nhỏ nhất ra thì không gì làm nó nhỏ hơn được nữa. Cạnh âm phá vỡ điều này — lúc đó phải dùng Bellman-Ford.
3. Chạy debug: Dijkstra từng bước
4. Code chạy được
Một đỉnh có thể bị đẩy vào heap nhiều lần với các khoảng cách khác nhau. Dòng if d > dist[u]: continue bỏ qua bản ghi đã lỗi thời, giúp thuật toán đúng và hiệu quả mà không cần xoá khỏi heap.
5. Phân tích
| Khía cạnh | Giá trị |
|---|---|
| Thời gian | O(E log V) với binary heap |
| Bộ nhớ | O(V + E) |
| Điều kiện | Trọng số không âm |
Bẫy thường gặp:
- Có cạnh âm → Dijkstra cho kết quả sai. Dùng Bellman-Ford.
- Quên kiểm tra bản ghi cũ → vẫn đúng nhưng làm nhiều việc thừa.
- So sánh sai: phải cập nhật khi
dist[v] > dist[u] + w.
6. Mẫu nhận diện
- "Đường đi ngắn nhất" + "cạnh có trọng số không âm" → Dijkstra.
- "Chi phí / thời gian / khoảng cách nhỏ nhất từ một điểm" → Dijkstra một nguồn.
- Bản đồ định tuyến, mạng, trò chơi có chi phí di chuyển khác nhau → Dijkstra.
7. 🎮 Trò chơi: Hiểu Dijkstra
8. Quiz kiểm tra nhanh
9. Hoàn thành
…☑️ Tiếp theo: 3.3.5 — Bellman-Ford & Floyd-Warshall (xử lý cạnh âm và mọi cặp đỉnh).