# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
335584 | jbroeksteeg | Commuter Pass (JOI18_commuter_pass) | C++14 | 0 ms | 0 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <iostream>
#include <climits>
#include <iomanip>
#include <math.h>
#include <numeric>
#include <cassert>
#include <algorithm>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <vector>
#include <array>
#include <memory>
#define IN(a,b) (a.find(b) != a.end())
#define p(a,b) make_pair(a,b)
#define readVec(a) for (int64_t __i = 0; __i<(int64_t)a.size();__i++){cin>>a[__i];}
// jimjam
template<typename T>
void pMin(T &a, T b) {if (b<a){a=b;}}
template<typename T>
void pMax(T &a, T b) {if (b>a){a=b;}}
template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& c);
template<typename A, typename B>
std::ostream& operator<<(std::ostream& os, const std::pair<A,B>& c) {std::cout << "(" << c.first << ", " << c.second << ")";return os;}
template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& c) {
if (c.size() == 0) {os << "{}"; return os;}
os << "{" << c[0];
for (int64_t i = 1; i < (int64_t)c.size(); i++) {os <<", "<<c[i];}
os << "}";
return os;
}
const int64_t inf = 2e18;
using namespace std;
int64_t n,m,s,t,u,v;
vector<vector<pair<int64_t,int64_t>>> adj;
vector<vector<int64_t>> backtrack;
vector<vector<int64_t>> dag;
vector<bool> topoSeen;
set<int> good;
vector<int> topoOrder;
void toposort(int c) {
topoSeen[c]=true;
for( int i: dag[c] ) {
if (!topoSeen[i]&&good.count(i)) toposort(i);
}
topoOrder.push_back(c);
}
void dijkstra(int64_t start, vector<int64_t>& seen) {
priority_queue<pair<int64_t,int64_t>,vector<pair<int64_t,int64_t>>,greater<pair<int64_t,int64_t>>> pq;
pq.push({0,start});
seen[start]=0;
while (pq.size()) {
auto curr = pq.top(); pq.pop();
for (pair<int64_t,int64_t> pi: adj[curr.second]) {
if (pi.second+curr.first<seen[pi.first]) {
seen[pi.first]=pi.second+curr.first;
pq.push({seen[pi.first],pi.first});
}
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
// s t get nuked
// route from u to v
cin >> n >> m >> s >> t >> u >> v;
adj.resize(n+1);
topoSeen.resize(n+1);
backtrack.resize(n+1);
dag.resize(n+1);
for (int64_t i = 0; i < m; i++) {
int64_t a, b, w; cin >> a >> b >> w;
adj[a].push_back({b,w});
adj[b].push_back({a,w});
}
priority_queue<pair<int64_t,int64_t>,vector<pair<int64_t,int64_t>>,greater<pair<int64_t,int64_t>>> pq;
vector<int64_t> dijkstraSeen(n+1,inf);
dijkstraSeen[s]=0;
pq.push({0, s});
while (pq.size()) {
auto curr = pq.top();
pq.pop();
for (auto pi: adj[curr.second]) {
if (pi.second+curr.first<dijkstraSeen[pi.first]) {
backtrack[pi.first].clear();
dijkstraSeen[pi.first]=pi.second+curr.first;
pq.push({dijkstraSeen[pi.first],pi.first});
}
if (pi.second+curr.first<=dijkstraSeen[pi.first]) {
backtrack[pi.first].push_back(curr.second);
}
}
}
vector<int64_t> distFromU(n+1,inf), distFromV(n+1,inf);
dijkstra(u,distFromU);
dijkstra(v,distFromV);
for (int i = 1; i <= n; i++) adj[i].clear();
for (int64_t i = 1; i <= n; i++) {
for (int64_t j: backtrack[i]) {
dag[j].push_back(i);
}
}
priority_queue<pair<int64_t,int64_t>> pq2; // goes through DAG backwards
vector<int64_t> minUBehind(n+1,inf), minVBehind(n+1,inf);
for (int64_t i = 1; i <= n; i++) {
minUBehind[i]=distFromU[i];
minVBehind[i]=distFromV[i];
}
queue<int> bfs; // bfs to find good edges
vector<int> bfsSeen(n+1);
bfs.push(t);
while (bfs.size()) {
good.insert(bfs.front());
for (int i: backtrack[bfs.front()]&&!bfsSeen[bfs.front()]) {
bfs.push(i);
bfsSeen[i]=true;
}
bfs.pop();
}
int64_t ans=inf;
for (int i: good) {
if (!topoSeen[i]) toposort(i);
}
reverse(topoOrder.begin(),topoOrder.end());
for( int currInd: topoOrder) {
pMin(ans, minUBehind[currInd] + distFromV[currInd]);
pMin(ans, minVBehind[currInd] + distFromU[currInd]);
for (int64_t i: dag[currInd]) {
pMin(minUBehind[i],minUBehind[currInd]);
pMin(minVBehind[i],minVBehind[currInd]);
}
}
cout << min(ans,distFromV[u]) << endl;
return 0;
}