Submission #60909

#TimeUsernameProblemLanguageResultExecution timeMemory
60909BenqCommuter Pass (JOI18_commuter_pass)C++11
100 / 100
762 ms89196 KiB

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;
 
typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

const int MOD = 1000000007;
const ll INF = 1e18;
const int MX = 100001;

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


template<int SZ> struct Dijkstra {
    ll dist[SZ];
    vpi adj[SZ];
    priority_queue<pl,vpl,greater<pl>> q;
    
    void addEdge(int A, int B, int C) {
        adj[A].pb({B,C}), adj[B].pb({A,C});
    }
    
    void gen(int st) {
        fill_n(dist,SZ,INF); 
        q = priority_queue<pl,vpl,greater<pl>>();
        
        dist[st] = 0; q.push({0,st});
    	while (sz(q)) {
    		pl x = q.top(); q.pop();
    		if (dist[x.s] < x.f) continue;
    		for (pi y: adj[x.s]) if (x.f+y.s < dist[y.f]) {
    			dist[y.f] = x.f+y.s;
    			q.push({dist[y.f],y.f});
    		}
    	}
    }
};

Dijkstra<MX> D;
ll dist[2][MX], DIST[2][MX];
pl mn[MX];
bool ok[MX];

pl comb(pl a, pl b) {
    return {min(a.f,b.f),min(a.s,b.s)};
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> N >> M >> S >> T >> U >> V;
    F0R(i,M) {
        int A,B,C; cin >> A >> B >> C;
        D.addEdge(A,B,C);
    }
    
    D.gen(U);
    FOR(i,1,N+1) dist[0][i] = D.dist[i];
    D.gen(V);
    FOR(i,1,N+1) dist[1][i] = D.dist[i];
    
    FOR(i,1,N+1) mn[i] = {INF,INF};
    D.gen(S);
    FOR(i,1,N+1) DIST[0][i] = D.dist[i];
    D.gen(T);
    FOR(i,1,N+1) DIST[1][i] = D.dist[i];
    
    ll ans = dist[0][V];
    vpl v; 
    FOR(i,1,N+1) if (DIST[0][i]+DIST[1][i] == DIST[0][T]) {
        ok[i] = 1;
        v.pb({DIST[0][i],i});
    }
    sort(v.rbegin(),v.rend());
    for (auto a: v) {
        for (auto t: D.adj[a.s]) if (ok[t.f]) mn[a.s] = comb(mn[a.s],mn[t.f]);
        ans = min(ans,min(mn[a.s].f+dist[1][a.s],mn[a.s].s+dist[0][a.s]));
        mn[a.s] = comb(mn[a.s],{dist[0][a.s],dist[1][a.s]});
    }
    cout << ans;
}

/* Look for:
* the exact constraints (multiple sets are too slow for n=10^6 :( ) 
* special cases (n=1?)
* overflow (ll vs int?)
* array bounds
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...