Hướng dẫn giải của Chặn Đường (Gold)
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Lời giải: Chặn Đường (Gold)
Hướng tiếp cận
Bài toán yêu cầu tìm một cạnh để nhân đôi độ dài sao cho đường đi ngắn nhất từ đến tăng nhiều nhất.
Nhận xét quan trọng
- Nếu cạnh được nhân đôi không nằm trên đường đi ngắn nhất hiện tại, thì đường đi ngắn nhất không thay đổi (vì đường cũ vẫn có thể dùng).
- Do đó, ta chỉ cần xét các cạnh nằm trên đường đi ngắn nhất từ đến .
- Một cạnh nằm trên đường đi ngắn nhất nếu: hoặc , trong đó là khoảng cách ngắn nhất ban đầu.
Thuật toán
- Chạy Dijkstra từ đỉnh để tính — khoảng cách ngắn nhất từ đến mọi đỉnh.
- Chạy Dijkstra từ đỉnh để tính — khoảng cách ngắn nhất từ đến mọi đỉnh.
- Khoảng cách ngắn nhất ban đầu: .
- Với mỗi cạnh nằm trên đường đi ngắn nhất:
- Thêm vào độ dài cạnh đó (vì nhân đôi = tăng thêm ), tạm thời chạy Dijkstra lại từ đến .
- Hoặc: dùng phương pháp không chạy Dijkstra lại — xét tất cả đường đi thay thế qua các cạnh khác trong sau khi đã có và .
- Thực tế với , : chạy Dijkstra cho từng cạnh trên đường đi ngắn nhất (tối đa cạnh) vẫn đủ nhanh — tổng .
- Đáp án là trên tất cả các cạnh đã thử.
Độ phức tạp
- Thời gian: (có thể tối ưu thành bằng cách không chạy lại Dijkstra hoàn toàn)
- Bộ nhớ:
Bình luận