#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <functional>
#include <cassert>
using namespace std;
//#define debug 1
#define int long long
int N, M;
int S, T;
int U, V;
//#define assert_in(a)assert(a < N);assert(a >= 0);
#define Qnode priority_queue<Node, vector<Node>, greater<Node>>
vector<map<int, int>> G;
class Node{
public:
int cost, node, from;
bool used=false;
const bool operator>(const Node& o) const{
return cost > o.cost;
}
const bool operator>=(const Node& o) const{
return cost >= o.cost;
}
const bool operator<=(const Node& o) const{
return cost <= o.cost;
}
const bool operator<(const Node& o) const{
return cost < o.cost;
}
};
vector<bool> is_solut;
vector<bool> is_in_solut(vector<vector<int>> G, int node){
vector<bool> visited(N, false);
function<void(int)> dfs;
dfs = [&](int node){
if(visited[node])return;
visited[node] = true;
for(int next_node:G[node]){
if(next_node == -1)continue;
if(!visited[next_node])
dfs(next_node);
}
};
dfs(node);
return visited;
}
const int INF = 1'000'000'000'000'000LL;
vector<int> dp;
vector<vector<int>> S_Ttree[2];
int dp_dfs(int node, bool used);
int call_recurs(int node, bool is_up){
int res = INF;
for(int next_node:S_Ttree[is_up][node]){
if(is_solut[next_node]){
res = min(res, dp_dfs(next_node, true));
res = min(res, call_recurs(next_node, is_up));
}
}
return res;
}
int deep = 0;
int dp_dfs(int node, bool used){
int key = node*2+used;
if(dp[key] != -1){
return dp[key];
}
dp[key] = INF;
for(auto A:G[node])
dp[key] = min(dp[key], dp_dfs(A.first, used)+A.second);
if(!used && is_solut[node]){
dp[key] = min(
dp[key],
min(
call_recurs(node, true),
call_recurs(node, false)
)
);
}
return dp[key];
}
signed main(){
cin >> N >> M;
cin >> S >> T;
cin >> U >> V;
S--, U--, T--, V--;
G = vector<map<int, int>>(N);
for(int i=0; i<M; i++){
int node0, node1, cost;
cin >> node0 >> node1 >> cost;
node0--, node1--;
G[node0][node1] = cost;
G[node1][node0] = cost;
}
Qnode Q;
vector<int> S_T(N, -1);
S_Ttree[0] = vector<vector<int>>(N);
S_Ttree[1] = vector<vector<int>>(N);
Q.push({0, S, -1});
while(!Q.empty()){
Node cur=Q.top();
Q.pop();
//cout << cur.node << ' ' << cur.from << ' ' << cur.cost << '\n';
if(S_T[cur.node] != -1){
if(S_T[cur.node] == cur.cost && cur.from != -1){
S_Ttree[1][cur.node].push_back(cur.from);
S_Ttree[0][cur.from].push_back(cur.node);
}
continue;
}
//if(cur.node == T)break;
S_T[cur.node] = cur.cost;
if(cur.from != -1){
S_Ttree[1][cur.node].push_back(cur.from);
S_Ttree[0][cur.from].push_back(cur.node);
}
for(auto A:G[cur.node]){
if(S_T[A.first] == -1)
Q.push({cur.cost+A.second, A.first, cur.node});
}
}
is_solut = is_in_solut(S_Ttree[1], T);
/*#ifdef debug
int temp=0;
for(vector<int> A:S_Tup){
cout << temp << " :";
for(int n:A)cout << ' ' << n;
cout << '\n';
temp++;
}
cout << '\n';
temp = 0;
for(vector<int> A:S_Tdown){
cout << temp << " :";
for(int n:A)cout << ' ' << n;
cout << '\n';
temp++;
}
for(int t:is_solut)cout << t << ' ';
cout << '\n';
#endif*/
dp = vector<int>(N*2, -1);
dp[V*2] = 0;
dp[V*2+1] = 0;
cout << dp_dfs(U, false) << '\n';
}
# | 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... |