fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. using ll = long long; // code chat em bị bạn em bắt nộp
  5. const ll INF = (ll)9e18;
  6.  
  7. int main() {
  8. ios::sync_with_stdio(false);
  9. cin.tie(nullptr);
  10.  
  11. int N, M;
  12. if (!(cin >> N >> M)) return 0;
  13.  
  14. if (N == 1) { cout << 0 << "\n"; return 0; }
  15.  
  16. struct Edge { int u, v; ll f; };
  17. vector<Edge> E(M);
  18.  
  19. // Mỗi cạnh -> 2 trạng thái: id_u = 2*i, id_v = 2*i+1
  20. int S = 2*M; // siêu nguồn (tần số 0 tại khoang 1)
  21. vector<vector<pair<int,ll>>> G(2*M + 1); // (to, w)
  22.  
  23. vector<vector<pair<ll,int>>> at(N+1);
  24. // at[u] = list { (freq f, state_id) } của các cạnh kề u
  25.  
  26. for (int i = 0; i < M; ++i) {
  27. int a,b; ll f;
  28. cin >> a >> b >> f;
  29. E[i] = {a,b,f};
  30. int id_u = 2*i, id_v = 2*i+1;
  31.  
  32. // qua lại trên chính hành lang i: chi phí 0
  33. G[id_u].push_back({id_v, 0});
  34. G[id_v].push_back({id_u, 0});
  35.  
  36. // gắn trạng thái vào hai đầu mút
  37. at[a].push_back({f, id_u});
  38. at[b].push_back({f, id_v});
  39. }
  40.  
  41. // Tạo các "cạnh đổi tần số" trong từng khoang bằng cách nối các tần số kề nhau sau khi sort
  42. for (int u = 1; u <= N; ++u) {
  43. auto &vec = at[u];
  44. if (vec.empty()) continue;
  45. sort(vec.begin(), vec.end(), [](auto &A, auto &B){
  46. if (A.first != B.first) return A.first < B.first;
  47. return A.second < B.second;
  48. });
  49. for (int i = 0; i + 1 < (int)vec.size(); ++i) {
  50. ll df = vec[i+1].first - vec[i].first; // >= 0
  51. int a = vec[i].second, b = vec[i+1].second;
  52. G[a].push_back({b, df});
  53. G[b].push_back({a, df});
  54. }
  55. }
  56.  
  57. // Nối siêu nguồn S -> một trạng thái ở khoang 1 có tần số nhỏ nhất
  58. if (at[1].empty()) {
  59. // đồ thị liên thông ⇒ khoang 1 phải có bậc > 0, nhưng cứ phòng hờ:
  60. cout << -1 << "\n";
  61. return 0;
  62. } else {
  63. // phần tử đầu sau khi sort ở trên là tần số nhỏ nhất
  64. // Nếu chưa sort, sort nhanh riêng cho at[1]
  65. sort(at[1].begin(), at[1].end(), [](auto &A, auto &B){
  66. if (A.first != B.first) return A.first < B.first;
  67. return A.second < B.second;
  68. });
  69. ll fmin = at[1][0].first;
  70. int sid = at[1][0].second;
  71. G[S].push_back({sid, fmin}); // từ 0 lên fmin
  72. }
  73.  
  74. // Dijkstra từ S
  75. int V = 2*M + 1;
  76. vector<ll> dist(V, INF);
  77. using P = pair<ll,int>;
  78. priority_queue<P, vector<P>, greater<P>> pq;
  79.  
  80. dist[S] = 0;
  81. pq.push({0, S});
  82.  
  83. while (!pq.empty()) {
  84. auto [du, u] = pq.top(); pq.pop();
  85. if (du != dist[u]) continue;
  86. for (auto [v, w] : G[u]) {
  87. if (dist[v] > du + w) {
  88. dist[v] = du + w;
  89. pq.push({dist[v], v});
  90. }
  91. }
  92. }
  93.  
  94. // Lấy min trên mọi trạng thái "đang ở khoang N"
  95. ll ans = INF;
  96. for (auto &[f, sid] : at[N]) ans = min(ans, dist[sid]);
  97.  
  98. cout << ans << "\n";
  99. return 0;
  100. }
  101.  
Success #stdin #stdout 0.01s 5292KB
stdin
Standard input is empty
stdout
Standard output is empty