Submission #1293773

#TimeUsernameProblemLanguageResultExecution timeMemory
1293773notbrainingCommuter Pass (JOI18_commuter_pass)C++20
55 / 100
251 ms34000 KiB
//#pragma GCC optimize ("O3")
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<iomanip>
#include <cassert>
#include<algorithm>
#include <cstring>
#include<unordered_set>
#include<queue>
#include <array>
#include<cmath>
#include<unordered_map>
#include<queue>
#include <list>
#include <bitset>
using namespace std;
#define int long long
#define pii pair<int,int>
#define LL long long
//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt”)
int n, m, s, t, u, v;
int INF = 1e18 / 3;
vector<vector<pii>>adj;
vector<vector<int>>pairwise_dists;
void floyd_warshall(){
    pairwise_dists = vector<vector<int>>(n + 1, vector<int>(n + 1, INF));
    for(int i = 1; i <= n; ++i){
        pairwise_dists[i][i] = 0;
        for(auto [j, C] : adj[i]){
            pairwise_dists[i][j] = C;
        }
    }
    for(int k = 1; k <= n; ++k){
        for(int i = 1; i <= n; ++i){
            for(int j = 1; j <= n; ++j){
                pairwise_dists[i][j] = min(pairwise_dists[i][k] + pairwise_dists[k][j], pairwise_dists[i][j]);
            }
        }
    }
}
void dijkstras(vector<int>& startnodes, vector<int>& dists, vector<vector<int>>& reachedfrom){
    reachedfrom = vector<vector<int>>(n + 1);
    dists = vector<int>(n + 1, INF);
    priority_queue<pair<int, pii>, vector<pair<int, pii>>, greater<pair<int, pii>>>pq;
    for(int j : startnodes){
        dists[j] = 0;
        pq.push({0, {j, -1}});
    }
    while(!pq.empty()){
        auto [d, foo] = pq.top();
        auto [curr, visfrom] = foo;
        pq.pop();
        for(auto [j, C] : adj[curr]){
            if(C + d < dists[j]){
                pq.push({C + d, {j, curr}});
                dists[j] = C + d;
            }
        }
    }
}
vector<int>t_dists, s_dists, v_dists, u_dists;
vector<vector<int>>t_reachedfrom, s_reachedfrom, v_reachedfrom, u_reachedfrom;
void solve0(){
    vector<int>tt = {t};
    vector<int>ss = {s};
    vector<int>vv = {v};
    vector<int>uu = {u};
    dijkstras(tt, t_dists, t_reachedfrom);
    dijkstras(ss, s_dists, s_reachedfrom);
    dijkstras(vv, v_dists, v_reachedfrom);
    dijkstras(uu, u_dists, u_reachedfrom);
}
void solve1(){
    //S =U, so 
    int totaldist = s_dists[t];
    //cout << totaldist << endl;
    int ans = INF;
    for(int i = 1; i <= n; ++i){
        if(s_dists[i] + t_dists[i] == totaldist){
            ans = min(ans, v_dists[i]);
        }
    }
    cout << ans;
}
void solve2(){
    //multi-source Dijkstras after finding S-T nodes
    int totaldist = s_dists[t];
    vector<int>multisource;
    for(int i = 1; i <= n; ++i){
        if(s_dists[i] + t_dists[i] == totaldist){
            multisource.push_back(i);
        }
    }
    vector<int>multisource_dists;
    vector<vector<int>>multisource_visfrom;
    dijkstras(multisource, multisource_dists, multisource_visfrom);
    int ans = v_dists[u];
    if(n <= 300){
        for(int i = 1; i <= n; ++i){
            for(int j = 1; j <= n; ++j){

                if(s_dists[i] + t_dists[j] + pairwise_dists[i][j] == totaldist){
                    //cout << i << " " << j << endl;
                    //cout << pairwise_dists[u][i] << " " << pairwise_dists[v][j] << endl;
                    ans = min(ans, (u_dists[i] + v_dists[j]));
                    ans = min(ans, (u_dists[j] + v_dists[i]));
                }
            }
        }
        cout << ans;
        return;
    }
    cout << min(multisource_dists[u] + multisource_dists[v], ans);
}
int32_t main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> m >> s >> t >> u >> v;
    adj = vector<vector<pii>>(n + 1);

    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});
    }
    if(n <= 300){
        floyd_warshall();
    }
    solve0();
    if(s == u){
        solve1();
    } else{
        solve2();
    }

}

#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...