Có n thành phố được đánh số từ 1 đến n và m chuyến bay một chiều. Chuyến bay từ a tới b có giá vé c.
Bạn cần đi từ thành phố 1 tới thành phố n và có một phiếu giảm giá. Phiếu phải được dùng cho đúng một chuyến bay trên hành trình. Nếu chuyến đó có giá c, số tiền phải trả cho nó là ⌊c/2⌋; giá của mọi chuyến còn lại giữ nguyên.
Hãy tìm tổng tiền nhỏ nhất cần trả. Dữ liệu bảo đảm luôn tồn tại ít nhất một hành trình từ 1 tới n.
Input
Dòng đầu chứa hai số nguyên n và m.
Mỗi trong m dòng tiếp theo chứa ba số nguyên a,b,c, biểu thị một chuyến bay một chiều từ a tới b có giá c.
Output
In tổng chi phí nhỏ nhất của một hành trình từ 1 tới n sau khi dùng phiếu đúng một lần.
Constraints
2≤n≤105.
1≤m≤2⋅105.
1≤a,b≤n.
1≤c≤109.
Cạnh tự khuyên và nhiều chuyến bay cùng đầu mút đều được phép.
Luôn có đường đi có hướng từ 1 tới n.
Scoring
Subtask 1 (50% số điểm): n≤40,m≤100.
Subtask 2 (50% số điểm): Không có giới hạn bổ sung.
Example
Test 1
Input
4 5
1 2 8
2 4 7
1 3 5
3 4 10
2 3 1
Output
10
Giải thích: Đi theo 1−>3−>4 và dùng phiếu cho chuyến giá 10, tổng tiền là 5+⌊10/2⌋=10. Mọi cách dùng phiếu trên các hành trình khác đều không rẻ hơn.
Test 2
Input
3 3
1 2 9
2 3 1
1 3 11
Output
5
Giải thích: Có thể bay thẳng và trả ⌊11/2⌋=5; hoặc đi qua thành phố 2, giảm chuyến giá 9 còn 4 rồi trả thêm 1, cũng được tổng 5.
Lời giải tóm tắt
Tách tại cạnh dùng phiếu: Giả sử phiếu được dùng trên cạnh u -> v có giá c. Phần trước cạnh này nên là đường rẻ nhất từ 1 tới u; phần sau nên là đường rẻ nhất từ v tới n. Ứng viên tương ứng là
Tách tại cạnh dùng phiếu:d1[u] + floor(c / 2) + dn[v].
Tách tại cạnh dùng phiếu: Ta chạy Dijkstra từ 1 trên đồ thị gốc để có d1. Để tính dn[v], đảo chiều tất cả cạnh rồi chạy Dijkstra từ n.
Thuật toán: 1. Tính d1[u], khoảng cách từ 1 tới mọi u. 2. Tính dn[v], khoảng cách từ mọi v tới n, bằng đồ thị đảo. 3. Thử từng cạnh gốc làm cạnh nhận phiếu và lấy ứng viên nhỏ nhất.
Chứng minh tính đúng đắn: Xét hành trình tối ưu và cạnh u -> v được giảm. Nếu đoạn trước không có chi phí d1[u], thay nó bằng đường rẻ nhất không làm tăng tổng tiền; tương tự với đoạn sau và dn[v]. Vì thế giá trị tối ưu xuất hiện trong một ứng viên mà thuật toán xét.
Chứng minh tính đúng đắn: Ngược lại, mỗi ứng viên ghép một đường từ 1 tới u, cạnh u -> v dùng phiếu và một đường từ v tới n, nên là một hành trình hợp lệ dùng phiếu đúng một lần. Do đó giá trị nhỏ nhất trong các ứng viên vừa không lớn hơn vừa không nhỏ hơn đáp án tối ưu, nên bằng đáp án.
Độ phức tạp: Thời gian O((n+m) log n), bộ nhớ O(n+m).