两种思路,正向做最长路和反向做最短路(使用dijkstra和SPFA实现都可以)
1.求手续费用最小等价于求保留最多,选择最多保留的路径
2.直接把最终得到的费用代入,反向往起点搜,选择代价最小的一条路,花费即路程
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int N = 2e5 + 5;
int n, m;
int start, endpos;
double d[N];
bool st[N];
int cnt, head[N];
struct bal{
int to, nxt;
double val;
};
bal e[N];
void add(int u, int v, double w) {
e[++cnt].nxt = head[u];
e[cnt].to = v;
e[cnt].val = 100 - w;
head[u] = cnt;
}
void spfa1(int x) {//反向
for(int i = 1; i <= n; i++)
d[i] = 1e10;
queue <int> q;
d[x] = 100;
q.push(x); st[x] = 1;
while(!q.empty()) {
int u = q.front(); q.pop();
st[u] = 0;
for(int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
double w = e[i].val;
if(d[v] > d[u] / (w / 100)) {
d[v] = d[u] / (w / 100);
if(!st[v]) {
q.push(v);
st[v] = 1;
}
}
}
}
}
void spfa2(int x) {//正向
queue <int> q;
d[x] = 1;
q.push(x); st[x] = 1;
while(!q.empty()) {
int u = q.front(); q.pop();
st[u] = 0;
for(int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
double w = e[i].val;
if(d[v] < d[u] * (w / 100)) {
d[v] = d[u] * (w / 100);
if(!st[v]) {
q.push(v);
st[v] = 1;
}
}
}
}
}
int main() {
cin >> n >> m;
for(int i = 1; i <= m; i++) {
int u, v, w;
cin >> u >> v >> w;
add(u, v, w); add(v, u, w);
}
cin >> start >> endpos;
spfa2(start);
printf("%.8lf\n", 100 / d[endpos]);
return 0;
}