RT,好崩溃
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <limits>
#include <queue>
#include <stack>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
inline ll read() {
register ll n = 0, s = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') s = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
n = (n << 1) + (n << 3) + c - '0';
c = getchar();
}
return s * n;
}
// T290665 [DMOI-R2] 梦境
int cnt, head[(int)2e5 + 5];
bool vis[(int)2e5 + 5];
int dist[(int)2e5];
struct node {
int num, pre;
ll dis;
bool vis = false;
bool operator<(const node &b) const {
if (dis == b.dis) {
return num > b.num;
}
return dis > b.dis;
}
node(int num = 0, ll dis = 0, int pre = 0) : num(num), dis(dis), pre(pre){};
} n[(int)2e5 + 5];
struct nd {
int num;
ll dis = 0;
bool vis = false;
bool operator<(const nd &b) const { return dis > b.dis; }
nd(int num = 0, ll dis = 0) : num(num), dis(dis){};
} n2[(int)2e5 + 5];
struct edge {
int from, to, nxt, len;
} e[(int)4e5 + 5];
inline void addEdge(const int &from, const int &to, const int &len) {
cnt++;
e[cnt].from = from;
e[cnt].to = to;
e[cnt].len = len;
e[cnt].nxt = head[from];
head[from] = cnt;
return;
}
void dijs_1(int root, int dest) {
priority_queue<node> q;
n[root].vis = true;
n[root].num = root;
for (int i = head[root]; i != 0; i = e[i].nxt) {
q.push(node{e[i].to, e[i].len, root});
}
while (!q.empty()) {
node cur = q.top();
q.pop();
if (n[cur.num].vis) {
continue;
}
n[cur.num] = cur;
n[cur.num].vis = true;
if (cur.num == dest) {
return;
}
for (int i = head[cur.num]; i != 0; i = e[i].nxt) {
q.push(node{e[i].to, cur.dis + e[i].len, cur.num});
}
}
return;
}
void dijs_2(int root) {
priority_queue<nd> q;
n2[root].vis = true;
n2[root].num = root;
for (int i = head[root]; i != 0; i = e[i].nxt) {
q.push(nd{e[i].to, e[i].len});
}
while (!q.empty()) {
nd cur = q.top();
q.pop();
if (n2[cur.num].vis) {
continue;
}
n2[cur.num] = cur;
n2[cur.num].vis = true;
for (int i = head[cur.num]; i != 0; i = e[i].nxt) {
q.push(nd{e[i].to, cur.dis + e[i].len});
}
}
return;
}
int main() {
cout.precision(20);
int nn = read(), m = read(), S = read(), B = read(), F = read();
double ans = numeric_limits<double>::max(), temp;
bool flag = false;
register int u, v, w;
for (int i = 0; i < m; i++) {
u = read(), v = read(), w = read();
addEdge(u, v, w);
addEdge(v, u, w);
}
dijs_1(S, F);
dijs_2(B);
for (int i = F; i != S; i = n[i].pre) {
if (n[i].dis * 3 >= n2[i].dis * 2) {
flag = true; // can catch
temp = (n[i].dis + n2[i].dis) / 5;
ans = ans < temp ? ans : temp;
}
}
if (flag) {
cout << "NO\n" << ans;
} else {
ans = n2[F].dis - 1.5 * n[F].dis;
cout << "YES\n" << ans;
}
return 0;
}