Submission #1110751

#TimeUsernameProblemLanguageResultExecution timeMemory
1110751michifiedCommuter Pass (JOI18_commuter_pass)C++17
100 / 100
1163 ms40464 KiB

#include <bits/stdc++.h>
#define ll long long
#define db double
#define imx INT_MAX
#define imn INT_MIN
#define lmx LLONG_MAX
#define lmn LLONG_MIN
#define ld long double
#define lid id * 2 + 1
#define rid id * 2 + 2
using namespace std;
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds; 
#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> 
#define ordered_llset tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> 

const ll mod = 1e9 + 7;

struct edge_t {
    int to;
    ll c;
};

struct pqelem_t {
    int at;
    ll c;
};

auto cmp = [](const pqelem_t& a, const pqelem_t& b){return a.c > b.c;};
priority_queue<pqelem_t, vector<pqelem_t>, decltype(cmp)> pq(cmp);

void dijkstra(vector<ll>& best, vector<vector<edge_t>>& adj, int src) {
    best[src] = 0;
    pq.push({src, 0});
    while (not pq.empty()) {
        pqelem_t cur = pq.top();
        pq.pop();
        if (cur.c > best[cur.at]) continue;
        for (auto& e : adj[cur.at]) {
            if (cur.c + e.c < best[e.to]) {
                best[e.to] = cur.c + e.c;
                pq.push({e.to, cur.c + e.c});
            }
        }
    }
}

vector<ll> dodp(vector<vector<edge_t>>& adj, int src, int dst, vector<ll>& vbest) {
    int n = adj.size();
    vector<ll> best(n, lmx);
    vector<vector<int>> cands(n);
    best[src] = 0;
    pq.push({src, 0});
    while (not pq.empty()) {
        pqelem_t cur = pq.top();
        pq.pop();
        if (cur.c > best[cur.at]) continue;
        for (auto& e : adj[cur.at]) {
            if (cur.c + e.c < best[e.to]) {
                best[e.to] = cur.c + e.c;
                cands[e.to].clear();
                cands[e.to].push_back(cur.at);
                pq.push({e.to, cur.c + e.c});
            } else if (cur.c + e.c == best[e.to]) cands[e.to].push_back(cur.at);
        }
    }
    vector<vector<int>> cands2(n);
    fill(best.begin(), best.end(), lmx);
    best[dst] = 0;
    pq.push({dst, 0});
    while (not pq.empty()) {
        pqelem_t cur = pq.top();
        pq.pop();
        if (cur.c > best[cur.at]) continue;
        for (auto& e : adj[cur.at]) {
            if (cur.c + e.c < best[e.to]) {
                best[e.to] = cur.c + e.c;
                cands2[e.to].clear();
                cands2[e.to].push_back(cur.at);
                pq.push({e.to, cur.c + e.c});
            } else if (cur.c + e.c == best[e.to]) cands2[e.to].push_back(cur.at);
        }
    }
    int i;
    for (i = 0; i < n; i++) {
        for (int elem : cands2[i]) cands[elem].push_back(i);
    }
    vector<vector<int>> dag(n);
    unordered_set<int> seen;
    for (i = 0; i < n; i++) {
        seen.clear();
        for (int elem : cands[i]) {
            if (seen.find(elem) != seen.end()) dag[i].push_back(elem);
            seen.insert(elem);
        }
    }
    vector<int> indeg(n);
    for (i = 0; i < n; i++) {
        for (int elem : dag[i]) indeg[elem]++;
    }
    vector<ll> dp(n, lmx >> 1);
    queue<int> q;
    q.push(dst);
    while (not q.empty()) {
        int cur = q.front();
        q.pop();
        dp[cur] = min(dp[cur], vbest[cur]);
        for (int to : dag[cur]) {
            indeg[to]--;
            if (indeg[to] == 0) q.push(to);
            dp[to] = min(dp[to], dp[cur]);
        }
    }
    return dp;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m, i, s, t, u, v;
    cin >> n >> m >> s >> t >> u >> v;
    s--;
    t--;
    u--;
    v--;
    vector<vector<edge_t>> adj(n);
    for (i = 0; i < m; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        a--;
        b--;
        adj[a].push_back({b, c});
        adj[b].push_back({a, c});
    }
    vector<ll> ubest(n, lmx), vbest(n, lmx), sbest(n, lmx);
    dijkstra(ubest, adj, u);
    dijkstra(vbest, adj, v);
    vector<ll> res1 = dodp(adj, s, t, vbest), res2 = dodp(adj, t, s, vbest);
    ll ans = ubest[v];
    for (i = 0; i < n; i++) ans = min(ans, ubest[i] + min(res1[i], res2[i]));
    cout << ans;
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...