제출 #482089

#제출 시각아이디문제언어결과실행 시간메모리
482089bill_linCommuter Pass (JOI18_commuter_pass)C++14
100 / 100
291 ms26896 KiB
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
using namespace std;
 
const ll INF = 1e15;

int n;
vector<vector<pii>> adj;
vector<vector<int>> spadj;

vector<ll> dp;
vector<ll> sp, dist_u, dist_v;

ll dfs(int node) {
    if (dp[node] != -1) return dp[node];
    ll best = dist_v[node];
    
    for (int dest : spadj[node]) {
        best = min(best, dfs(dest));
    }
    return dp[node] = best;
}

vector<ll> dijkstra(int start_node) {
    vector<ll> dist(n + 1, INF);
    priority_queue<pll, vector<pll>, greater<pll>> q;
    dist[start_node] = 0;
    q.push({0, start_node});
    
    while (!q.empty()) {
        auto p = q.top();
        q.pop();
        ll curr_cost = p.first, node = p.second;
        for (pii &edge : adj[node]) {
            int dest = edge.first, edge_cost = edge.second;
            if (dist[dest] > curr_cost + edge_cost) {
                dist[dest] = curr_cost + edge_cost;
                q.push({dist[dest], dest});
            }
        }
    }
    
    return dist;
}



int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int m, S, T, U, V;
    cin >> n >> m >> S >> T >> U >> V;
    
    adj.resize(n + 1);
    spadj.resize(n + 1);
    for (int i = 0; i < m; i++) {
        int u, v, cost;
        cin >> u >> v >> cost;
        adj[u].push_back({v, cost});
        adj[v].push_back({u, cost});
    }

    // shortest path, dist to u, dist to v
    sp = dijkstra(S), dist_u = dijkstra(U), dist_v = dijkstra(V);
    vector<bool> vis(n + 1, false);
    // construct the shortest path
    queue<int> q;
    q.push(T);
    while (!q.empty()) {
        int node = q.front();
        q.pop();
        
        ll mn_dist = INF;
        for (pii &edge : adj[node]) {
            mn_dist = min(mn_dist, sp[edge.first]);
        }
        for (pii &edge : adj[node]) {
            int dest = edge.first, edge_cost = edge.second;
            if (sp[dest] + edge_cost == sp[node]) {
                spadj[node].push_back(dest);
                if (!vis[dest]) {
                    vis[dest] = true;
                    q.push(dest);
                }
            }
        }
    }
    
    // dfs from T, calculate, reverse spadj and dfs from S and recalculate
    ll best = dist_v[U];
    dp = vector<ll>(n + 1, -1);
    
    for (int i = 1; i <= n; i++) {
        dfs(i);
        best = min(best, dp[i] + dist_u[i]);
    }
    
    
    vector<vector<int>> tmp(n + 1);
    // reverse the edges
    for (int i = 1; i <= n; i++) {
        for (int j : spadj[i]) {
            tmp[j].push_back(i);
        }
    }
    
    spadj = tmp;
    dp = vector<ll>(n + 1, -1);
    for (int i = 1; i <= n; i++) {
        dfs(i);
        best = min(best, dp[i] + dist_u[i]);
    }
    
    cout << best << '\n';
    
    
    
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...