Submission #1364161

#TimeUsernameProblemLanguageResultExecution timeMemory
1364161lucaskojimaCommuter Pass (JOI18_commuter_pass)C++17
100 / 100
914 ms93272 KiB
#include "bits/stdc++.h"

using namespace std;

const long long INF = LLONG_MAX;

template<class T> int id(T x, vector<T> &a) {
  return lower_bound(a.begin(), a.end(), x) - a.begin() + 1;
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0);

  int N, M; cin >> N >> M;
  int S, T; cin >> S >> T;
  int U, V; cin >> U >> V;

  vector<vector<pair<int, int>>> adj(N + 1);
  map<pair<int, int>, int> ed;

  for (int i = 0; i < M; i++) {
    int a, b, c; cin >> a >> b >> c;
    adj[a].push_back({b, c});
    adj[b].push_back({a, c});
    ed[{a, b}] = ed[{b, a}] = c;
  }

  auto dijkstra = [](vector<int> S, auto &adj) -> vector<long long> {
    const int N = int(size(adj)) - 1;

    using T = pair<long long, int>;
    priority_queue<T, vector<T>, greater<T>> pq;
    vector<long long> dist(N + 1, INF);

    auto push = [&](int x, long long d) -> void {
      if (d < dist[x])
        pq.push({dist[x] = d, x});
    };
    for (int x : S)
      push(x, 0);

    while (!pq.empty()) {
      auto [d, x] = pq.top(); pq.pop();
      if (dist[x] != d) continue;

      for (auto [k, dd] : adj[x])
        push(k, d + dd);
    }
    return dist;
  };

  auto dist_S = dijkstra(vector<int>{S}, adj);
  auto dist_T = dijkstra(vector<int>{T}, adj);

  auto in_path = [&](int v) -> bool {
    return dist_S[v] + dist_T[v] == dist_S[T];
  };
  auto can_go_S = [&](int x, int y) -> bool {
    return dist_S[x] + ed[{x, y}] == dist_S[y] && in_path(x) && in_path(y);
  };
  auto can_go_T = [&](int x, int y) -> bool {
    return dist_T[x] + ed[{x, y}] == dist_T[y] && in_path(x) && in_path(y);
  };

  vector<pair<int, int>> B;
  for (int i = 1; i <= N; i++)
    for (int j = 0; j <= 3; j++)
      B.push_back({i, j});

  vector<vector<pair<int, int>>> g(4 * N + 1);
  for (int x = 1; x <= N; x++)
    for (auto [k, w] : adj[x]) {
      g[id({x, 0}, B)].push_back({id({k, 0}, B), w});
      if (in_path(k)) {
        g[id({x, 0}, B)].push_back({id({k, 1}, B), w});
        g[id({x, 0}, B)].push_back({id({k, 2}, B), w});
      }
      if (can_go_S(x, k))
        g[id({x, 1}, B)].push_back({id({k, 1}, B), 0});
      if (can_go_T(x, k))
        g[id({x, 2}, B)].push_back({id({k, 2}, B), 0});
      if (in_path(x)) {
        g[id({x, 1}, B)].push_back({id({k, 3}, B), w});
        g[id({x, 2}, B)].push_back({id({k, 3}, B), w});
      }
      g[id({x, 3}, B)].push_back({id({k, 3}, B), w});
    }

  vector<int> Z = {id({U, 0}, B)};
  if (in_path(U)) {
    Z.push_back(id({U, 1}, B));
    Z.push_back(id({U, 2}, B));
  }

  auto d = dijkstra(Z, g);

  long long ans = INF;
  for (int j = 0; j <= 3; j++)
    ans = min(ans, d[id({V, j}, B)]);

  cout << ans << '\n';
  return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...