Files
problemas-para-competicao-p…/quase-menor-caminho/src/ac.cpp

70 lines
1.8 KiB
C++

#include <bits/stdc++.h>
#define INF 0x7FFFFFFF
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
using graph = vector<vector<pll>>;
const int MAXN = 510;
vector<ll> dijk(int x, graph& g) {
priority_queue<pll> pq;
pq.push({0, x});
vector<ll> dist(MAXN, INF);
while (pq.size()){
auto [w, v] = pq.top();
pq.pop();
w = -w;
if (dist[v] <= w) continue;
dist[v] = w;
for (auto [u, ww] : g[v]) {
if (dist[u] <= w + ww) continue;
pq.push({-(w+ww), u});
}
}
return dist;
}
ll almost_dijk(int s, int d, graph& g, vector<ll>& dist_s, vector<ll>& dist_d) {
ll best = dist_s[d];
if (best == INF) return -1;
priority_queue<pll> pq;
pq.push({0, s});
vector<ll> dist(MAXN, INF);
while (pq.size()){
auto [w, v] = pq.top();
pq.pop();
w = -w;
if (v == d) return w;
if (dist[v] <= w) continue;
dist[v] = w;
for (auto [u, ww] : g[v]) {
if (dist_s[v] + ww + dist_d[u] <= best) continue; // pula essa aresta, corresponde a um caminho minimo
if (dist[u] <= w + ww) continue;
pq.push({-(w+ww), u});
}
}
return -1;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, m;
while (cin>>n>>m, n!=0 && m!=0){
int s, d; cin >> s >> d;
vector<vector<pll>> g(MAXN);
vector<vector<pll>> g_rev(MAXN);
for (int i=0;i<m;i++){
int u,v,p; cin >> u >> v >> p;
g[u].push_back({v, p});
g_rev[v].push_back({u, p});
}
vector<ll> dist_s = dijk(s, g);
vector<ll> dist_d = dijk(d, g_rev);
cout << almost_dijk(s, d, g, dist_s, dist_d) << '\n';
}
}