【Bellman-Ford】
【Bellman-Ford】
最短路算法
https://www.acwing.com/problem/content/855/
※求带有负权边的最短路
※若限制只能经过k条边->只能用Bellman-Ford
※时间复杂度:\(O(nm)\)
※若图带有负环->不一定有最短路
无最短路
有最短路
思路
//不用邻接表存图->只存边信息
for n次
for 所有边 a b w (松弛操作)
dist[b]=min(dist[b],dist[a]+w)
//三角不等式
dist[b]<=dist[a]+w
代码
※注意
(1)每次更新都只使用上一次迭代的结果:dist数组要备份
(2)考虑到(无穷大-负权边):判断不存在结果时 只需要大于一个很大的数就行(0x3f3f3f33f/2)
#include<bits/stdc++.h>
using namespace std;
const int N=510,M=10010;
struct Edge{
int a,b,w;
}edge[M];//存边
int n,m,k;
int dist[N];
int last[N];//只能在上一次迭代的结果下操作->需要备份
void bellman_ford(){
memset(dist,0x3f,sizeof dist);
dist[1]=0;
for(int i=0;i<k;i++){
//备份
memcpy(last,dist,sizeof dist);
for(int j=0;j<m;j++){
auto e=edge[j];
//用上一次的数据来计算
dist[e.b]=min(dist[e.b],last[e.a]+e.w);
}
}
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
edge[i]={a,b,c};
}
bellman_ford();
//注意这里:大于一个很大的数就行 不能是无穷大(存在无穷大-负权边)
if(dist[n]>0x3f3f3f3f/2) printf("impossible");
else printf("%d",dist[n]);
return 0;
}