1 条题解
-
0
自动搬运
来自洛谷,原作者为

The_BJX
QQ:3391087121搬运于
2025-08-24 21:44:16,当前版本为作者最后更新于2021-08-19 11:42:05,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
前言
瞎写了个 SPFA 就切掉了。
其他题解都 WA 了。所以我写了个正确的。题意简述
求有向图上的最短路,路径的权值为经过的所有边的权值之和。
有人因为没发现是有向图而 WA 掉了。
为什么要用 SPFA?
看到图上求权值最小的路径之类的问题时,可以很容易想到需要最短路算法。
此题的距离依照题意,就是边权的乘积。因此将松弛部分改一下即可。
因此这里的负环指的是一个边权之积小于 1 的环。如果一直沿着这个环走,价格就会越走越低,没有最小值(
最后就可以白嫖了)。所以此题要判负环。然而我只会 SPFA。AC 代码:
#include <iostream> #include <iomanip> #include <cstring> #include <queue> #define ll long double//用 long double 不然会被卡精度去世 using namespace std; const ll inf = 9982443500; struct edge{ int to; int next; ll w; }edges[600000]; int head[30000]; int tot; void add(int a, int b, ll w) { edges[++tot].to=b; edges[tot].w=w; edges[tot].next=head[a]; head[a]=tot; }//前向星基操 int n,m,a,b; ll v; queue<int> sp;//SPFA 的主队列 bool in[30000];//某一个点是否现在在队列里 int count[30000];//各店入队的次数 ll dis[30000];//源点到各店的距离 void push(int x) { if(!in[x]) { sp.push(x); in[x]=true; count[x]++; } } bool spfa(int f) { while(!sp.empty())sp.pop(); push(f); dis[f]=1; while(!sp.empty()) { int x=sp.front(); sp.pop(); in[x]=false; for (int i = head[x]; i; i=edges[i].next) { int y=edges[i].to; if(dis[y]>dis[x]*edges[i].w) { dis[y]=dis[x]*edges[i].w;//注意是乘积! if(!in[y]) { push(y); if(count[y]>n) { return true; //判断负环,如果入队次数大于点数说明有负环 } } } } } return false; } int main() { cin >> n >> m >> v >> a >> b; for (int i = 1; i <= n; i++) { dis[i]=inf; } for (int i = 0; i < m; i++) { int u,v; ll w; cin >> u >> v >> w; add(u,v,w); } if(spfa(a))cout << 0; else cout << fixed << setprecision(6) << dis[b]*v;//记得乘原价 }蒟蒻的第一篇题解求过 qwq 啊啊啊!
- 1
信息
- ID
- 2065
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者