Submission #335586

#TimeUsernameProblemLanguageResultExecution timeMemory
335586jbroeksteegCommuter Pass (JOI18_commuter_pass)C++14
100 / 100
607 ms35044 KiB
#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()]) {
			if (!bfsSeen[i]) {
				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;
}


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