Submission #1236577

#TimeUsernameProblemLanguageResultExecution timeMemory
1236577imannCommuter Pass (JOI18_commuter_pass)C++20
100 / 100
425 ms24184 KiB
#include <iostream>
#include <array>
#include <vector>
#include <queue>
#include <limits>

using ll = long long;

const ll MAX_N = 1000*100 + 2;

std::array<std::vector<std::pair<ll, ll>>, MAX_N> graph;

void dijkstra(ll startNode, std::array<ll, MAX_N> &dist) {
    using T = std::pair<ll, ll>;
    std::priority_queue<T, std::vector<T>, std::greater<T>> pq;
    dist.fill(std::numeric_limits<ll>::max());
    pq.push({0, startNode});
    dist[startNode] = 0;
    while (!pq.empty()) {
        auto [sDist, node] = pq.top();
        pq.pop();
        if (sDist != dist[node])
            continue;
        for (auto nei : graph[node]) {
            if (dist[nei.first] > sDist + nei.second) {
                dist[nei.first] = sDist + nei.second;
                pq.push({dist[nei.first], nei.first});
            }
        }
    }
}

ll solve(ll n, ll m, ll s, ll t, ll u, ll v) {
    std::array<ll, MAX_N> sDist, tDist, uDist, vDist;
    dijkstra(s, sDist);
    dijkstra(t, tDist);
    dijkstra(u, uDist);
    dijkstra(v, vDist);
    ll uvDist = uDist[v];
    ll stDist = sDist[t];

    using T = std::pair<ll, ll>;
    std::priority_queue<T, std::vector<T>, std::greater<T>> pq;
    std::array<ll, MAX_N> sFromUDist, sFromVDist, ssDist;
    sFromUDist.fill(std::numeric_limits<ll>::max());
    sFromVDist.fill(std::numeric_limits<ll>::max());
    ssDist.fill(std::numeric_limits<ll>::max());
    ssDist[s] = 0;
    pq.push({0, s});
    sFromUDist[s] = uDist[s];
    sFromVDist[s] = vDist[s];
    while (!pq.empty()) {
        auto [dist, node] = pq.top();
        pq.pop();
        if (dist != ssDist[node])
            continue;
        for (auto nei : graph[node]) {
            if (ssDist[nei.first] > dist + nei.second) {
                ssDist[nei.first] = dist + nei.second;
                pq.push({ssDist[nei.first], nei.first});
                sFromUDist[nei.first] = std::min(sFromUDist[node], uDist[nei.first]);
                sFromVDist[nei.first] = std::min(sFromVDist[node], vDist[nei.first]);
            } else if (ssDist[nei.first] == dist + nei.second) {
                sFromUDist[nei.first] = std::min(sFromUDist[nei.first], sFromUDist[node]);
                sFromUDist[nei.first] = std::min(sFromUDist[nei.first], uDist[nei.first]);
                sFromVDist[nei.first] = std::min(sFromVDist[nei.first], sFromVDist[node]);
                sFromVDist[nei.first] = std::min(sFromVDist[nei.first], vDist[nei.first]);
            }
        }
    }

    pq = {};
    std::array<ll, MAX_N> tFromUDist, tFromVDist, ttDist;
    tFromVDist.fill(std::numeric_limits<ll>::max());
    tFromUDist.fill(std::numeric_limits<ll>::max());
    ttDist.fill(std::numeric_limits<ll>::max());
    ttDist[t] = 0;
    pq.push({0, t});
    tFromVDist[t] = vDist[t];
    tFromUDist[t] = uDist[t];
    while (!pq.empty()) {
        auto [dist, node] = pq.top();
        pq.pop();
        if (dist != ttDist[node])
            continue;
        for (auto nei : graph[node]) {
            if (ttDist[nei.first] > dist + nei.second) {
                ttDist[nei.first] = dist + nei.second;
                pq.push({ttDist[nei.first], nei.first});
                tFromVDist[nei.first] = std::min(tFromVDist[node], vDist[nei.first]);
                tFromUDist[nei.first] = std::min(tFromUDist[node], uDist[nei.first]);
            } else if (ttDist[nei.first] == dist + nei.second) {
                tFromVDist[nei.first] = std::min(tFromVDist[nei.first], tFromVDist[node]);
                tFromVDist[nei.first] = std::min(tFromVDist[nei.first], vDist[nei.first]);
                tFromUDist[nei.first] = std::min(tFromUDist[nei.first], tFromUDist[node]);
                tFromUDist[nei.first] = std::min(tFromUDist[nei.first], uDist[nei.first]);
            }
        }
    }
    ll ans = std::numeric_limits<ll>::max();
    for (int i = 0; i < n; ++i) {
        if (sDist[i] + tDist[i] == stDist) {
            ans = std::min(ans, sFromUDist[i] + tFromVDist[i]);
            ans = std::min(ans, sFromVDist[i] + tFromUDist[i]);
        }
    }
    if (ans > uvDist)
        return uvDist;
    return ans;
}

int main() {
    int n, m; std::cin >> n >> m;
    int s, t; std::cin >> s >> t; s--; t--;
    int u, v; std::cin >> u >> v; u--; v--;
    for (int i = 0; i < m; ++i) {
        int a, b, c; std::cin >> a >> b >> c; a--; b--;
        graph[a].push_back({b, c});
        graph[b].push_back({a, c});
    }
    std::cout << solve(n, m, s, t, u, v) << std::endl;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...