#include <iostream>
#include <stack>
#include <queue>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <climits>
#include <cmath>
#include <unordered_map>
#include <unordered_set>
#include <numeric>
#include <iomanip>
#include <cstring>
#include <stdio.h>
#include <assert.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<string> vs;
typedef vector<long long> vll;
typedef pair<ll,ll> pll;
#define double long double
#define F first
#define S second
const double eps = 1e-9;
#define FOR(i,a,b) for(long long i=a;i<b;i++)
#define all(v) v.begin(),v.end()
// Define MAXN here, globally accessible
const ll MAXN = 1e17; // A sufficiently large value for infinity
template <typename I>
void print(vector<I> &v){
    FOR(i,0,v.size()){cout << v[i] << " ";}
    cout << "\n";
}
ll gcd(ll a,ll b){
    if(a==0){return b;}
    else if(b==0){return a;}
    else if(a<b){return gcd(b%a,a);}
    else{return gcd(a%b,b);}
}
ll lcm(ll a,ll b){
    return (a/gcd(a,b))*b;
}
// Global variable or passed by reference to avoid recreating
// Used to store edges on *any* shortest path from s to t
vector<vector<pll>> special_edges_adj;
vector<vector<pll>> special_edges_rev_adj; // For the "adj2" equivalent
// Visited array for DFS to prevent cycles in the shortest path reconstruction
vector<bool> dfs_visited;
vll dist_s_global; // Store dist from s globally or pass around
// build_shortest_path_edges function (removed as it was causing confusion with prev logic,
// and the BFS queue approach directly builds special_edges_adj)
/*
void build_shortest_path_edges(ll current_node, ll target_s_end, const vector<vector<pll>>& adj_original) {
    // ... (This function's logic was superseded by the BFS queue in solve)
}
*/
ll func(vector<vector<pll>> &adj_original, vector<vector<pll>> &additional_adj, ll n, ll u_query, ll v_query){
    vll dist(n,MAXN); // MAXN is now in scope
    vector<bool> visited(n,false);
    priority_queue<pll,vector<pll>,greater<pll>> pq;
    pq.push({0,u_query});
    dist[u_query] = 0;
    while(!pq.empty()){
        pll c = pq.top();
        pq.pop();
        ll current_d = c.F;
        ll current_u = c.S;
        if(visited[current_u]) continue;
        visited[current_u] = true;
        for(pll &p : adj_original[current_u]){
            ll alt = current_d + p.S;
            if(alt < dist[p.F]){
                dist[p.F] = alt;
                pq.push({alt,p.F});
            }
        }
        for(pll &p : additional_adj[current_u]){
            ll alt = current_d + p.S;
            if(alt < dist[p.F]){
                dist[p.F] = alt;
                pq.push({alt,p.F});
            }
        }
    }
    return dist[v_query];
}
void solve(){
    ll n,m;
    cin >> n >> m;
    n++;
    ll s_start, t_end;
    cin >> s_start >> t_end;
    ll u_query, v_query;
    cin >> u_query >> v_query;
    vector<vector<pll>> adj_original(n);
    for(ll i=0; i<m; ++i){
        ll a,b,c;
        cin >> a >> b >> c;
        adj_original[a].push_back({b,c});
        adj_original[b].push_back({a,c});
    }
    dist_s_global.assign(n, MAXN); // MAXN is now in scope
    vector<bool> visited_dijkstra(n, false);
    priority_queue<pll,vector<pll>,greater<pll>> pq_s;
    pq_s.push({0,s_start});
    dist_s_global[s_start] = 0;
    while(!pq_s.empty()){
        pll c = pq_s.top();
        pq_s.pop();
        ll current_d = c.F;
        ll current_u = c.S;
        if(visited_dijkstra[current_u]) continue;
        visited_dijkstra[current_u] = true;
        for(pll &p : adj_original[current_u]){
            ll alt = current_d + p.S;
            if(alt < dist_s_global[p.F]){
                dist_s_global[p.F] = alt;
                pq_s.push({alt,p.F});
            }
        }
    }
    special_edges_adj.assign(n, vector<pll>());
    special_edges_rev_adj.assign(n, vector<pll>());
    // dfs_visited.assign(n, false); // No longer needed for DFS if using BFS queue for special edges
    queue<ll> q_sp;
    q_sp.push(t_end);
    vector<bool> sp_visited_q(n, false);
    sp_visited_q[t_end] = true;
    while(!q_sp.empty()){
        ll current = q_sp.front();
        q_sp.pop();
        for(const pll& edge : adj_original[current]){
            ll neighbor = edge.F;
            ll weight = edge.S;
            // This condition correctly identifies if 'neighbor' is a predecessor of 'current'
            // on a shortest path from 's_start'
            if (dist_s_global[neighbor] != MAXN && dist_s_global[current] != MAXN &&
                dist_s_global[neighbor] + weight == dist_s_global[current]) {
                special_edges_adj[current].push_back({neighbor, 0});
                special_edges_rev_adj[neighbor].push_back({current, 0});
                if (!sp_visited_q[neighbor]) {
                    sp_visited_q[neighbor] = true;
                    q_sp.push(neighbor);
                }
            }
        }
    }
    cout << min(func(adj_original, special_edges_adj, n, u_query, v_query),
                func(adj_original, special_edges_rev_adj, n, u_query, v_query)) << "\n";
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll t=1;
    while(t--){
        solve();
    }
    return 0;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |