Hướng dẫn giải của Vé Tham Quan
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: Vé Tham Quan
Hướng tiếp cận
Bài toán yêu cầu tìm chi phí tối thiểu từ mỗi trạm để phủ được cả trạm và trạm . Ta mô hình bài toán dưới dạng đường đi ngắn nhất (shortest path) trên một đồ thị mở rộng.
Nhận xét quan trọng
Mô hình đồ thị mở rộng: Tạo đồ thị với đỉnh: đỉnh cho các trạm và đỉnh cho các vé. Đỉnh-vé kết nối với tất cả đỉnh-trạm trong đoạn bằng cạnh chi phí (khi đã "kích hoạt" vé, ta đi vào các trạm miễn phí). Cạnh từ đỉnh-trạm đến đỉnh-vé có chi phí (mua vé).
Dijkstra ba pha: Thay vì tìm đường đi ngắn nhất riêng lẻ cho mỗi trạm, ta chạy ba lần Dijkstra:
- Pha 1: Tính khoảng cách ngắn nhất từ trạm đến mọi đỉnh.
- Pha 2: Tính khoảng cách ngắn nhất từ trạm đến mọi đỉnh.
- Pha 3: Kết hợp: với mỗi đỉnh, khởi tạo , rồi chạy Dijkstra một lần nữa để tính chi phí tối thiểu cho mỗi trạm xuất phát.
Segment tree để xử lý interval: Mỗi vé phủ một đoạn . Khi xử lý một trạm trong Dijkstra, ta cần tìm tất cả các vé có đoạn chứa trạm đó. Dùng segment tree lưu các vé theo đoạn, và xóa vé sau khi xử lý (mỗi vé chỉ được xử lý đúng một lần).
Thuật toán
Bước 1: Đọc input và sắp xếp vé
Sắp xếp các vé theo (đầu trái của đoạn).
Bước 2: Dijkstra với Segment Tree
Hàm dijkstra(dist):
- Khởi tạo segment tree lưu giá trị (đầu phải) của các vé, sắp xếp theo .
- Với mỗi đỉnh-trạm lấy từ priority queue:
- Dùng segment tree tìm tất cả vé mà (tức là vé phủ trạm ).
- Xóa các vé đã tìm được khỏi segment tree.
- Cập nhật: nếu đỉnh-vé chưa được thăm tốt hơn, cập nhật chi phí và thêm vào priority queue với chi phí .
Bước 3: Ba pha Dijkstra
- Pha 1: , chạy Dijkstra.
- Pha 2: , chạy Dijkstra.
- Pha 3: , chạy Dijkstra.
Bước 4: Xuất kết quả
Với mỗi trạm , nếu thì in , ngược lại in .
Độ phức tạp
- Thời gian: — mỗi vé được xử lý đúng một lần trong segment tree, Dijkstra chạy 3 lần.
- Bộ nhớ:
Bình luận