Floyd-Warshall¶
Khái quát¶
Floyd-Warshall là thuật toán tìm đường đi ngắn nhất giữa tất cả cặp đỉnh trong đồ thị.
Thuật toán này do Robert Floyd phát minh năm 1962 và Stephen Warshall cải tiến năm 1962.
Ý tưởng chính của thuật toán là duyệt qua tất cả các cặp đỉnh và cập nhật đường đi ngắn nhất giữa chúng thông qua đỉnh trung gian.
Floyd-Warshall có thể áp dụng cho đồ thị:
- Có hướng hoặc vô hướng
- Có trọng số hoặc không trọng số
- Có chu trình âm, nhưng không thể xác định chu trình âm cụ thể.
Độ phức tạp của thuật toán là \(O(n^3)\), với \(n\) là số đỉnh của đồ thị.
Bài toán¶
Yêu cầu¶
Tìm đường đi ngắn nhất từ đỉnh start đến đỉnh finish bằng thuật toán Floyd-Warshall.
Input¶
Output¶
Giải thích¶
Input:
- Dòng đầu tiên chứa bốn số lần lượt là: 6 đỉnh, 10 cạnh, đỉnh xuất phát là 1 và đỉnh đích là 5.
- Mỗi dòng tiếp theo chứa hai đỉnh theo chiều từ u đến v và khoảng cách giữa chúng.
Phác thảo đồ thị theo input như sau:
Output:
- Dòng đầu tiên là khoảng cách ngắn nhất từ đỉnh start đến đỉnh finish. Cụ thể, khoảng cách ngắn nhất từ đỉnh 1 đến đỉnh 5 là 6.
- Dòng thứ hai liệt kê các đỉnh nằm trên đường đi tìm được: 1 -> 2 -> 4 -> 3 -> 6 -> 5.
Viết chương trình¶
Đọc input¶
Lưu dòng đầu tiên của input vào bốn biến number_of_vertices
, number_of_edges
, start
, finish
.
Đọc các dòng còn lại của input và biểu diễn các cạnh của đồ thị bằng ma trận kề graph
, với graph[u][v]
là trọng số của cạnh u -> v.
Thực hiện Floyd-Warshall¶
Bước 0: Khởi tạo
Khởi tạo mảng hai chiều trace
với trace[u][v]
lưu đỉnh trung gian cuối cùng trên đường đi ngắn nhất từ u đến v.
Bước 1: Duyệt đỉnh và cập nhật đường đi
Duyệt từng đỉnh trung gian k
và duyệt từng cặp đỉnh u
, v
:
Nếu có thể đi từ đỉnh u
đến đỉnh v
nhanh hơn bằng cách đi thông qua đỉnh k
thì:
- Cập nhật lại khoảng cách từ
u
đếnv
. - Lưu vết đường đi từ
u
đếnv
thông quak
vào mảngtrace
.
Truy vết đường đi¶
Truy vết từ đỉnh start
đến đỉnh finish
và lưu vào ngăn xếp path
.
In kết quả¶
Dựa vào ngăn xếp path
, ta in ra đường đi bằng cách lấy từng phần tử ra khỏi ngăn xếp.
Mã nguồn¶
Code đầy đủ được đặt tại GitHub.