ballman-ford解决有边数限制带负权最短路
存在边权为负的最短路径。
Dijkstra算法不能处理带负权边的问题。
使用ballman-ford可以解决这个问题。解决核心:松弛操作
输入
第一行包含三个整数 n,m,k。
接下来 m 行,每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。
点的编号为 1∼n。
3 3 1
1 2 1
2 3 1
1 3 3
输出
输出一个整数,表示从 1 号点到 n 号点的最多经过 k 条边的最短距离。
3
//Dijkstra不能解决负权边最短路问题
//原因:无法在st[]数组中进行确认,当前点的距离为最短
//bellman-ford算法特点
//松弛操作:dis[b]=min(dis[b], backup[a]+w)
#include<iostream>
using namespace std;
#include<cstring>
int n,m,k;
const int N=520, M=10010, MAX=0x3f3f3f3f;
int dis[N];
int backup[N];//备份数组防止串联
//创建edge存储每条边
struct Edge{
int a;
int b;
int w;
} e[M];
void bellman_ford(){
//初始化
memset(dis, MAX, sizeof dis);//初始化距离矩阵
dis[1]=0;
for(int i=0;i<k;i++){
memcpy(backup, dis, sizeof dis);//备份距离矩阵
for(int j=0; j<m; j++){
int a=e[j].a, b=e[j].b, w=e[j].w;//取出路径
dis[b] = min(dis[b] , backup[a]+w);//松弛操作
}
}
}
int main(){
cin>>n>>m>>k;
int a,b,w;
for(int i=0;i<m;i++){
cin>>a>>b>>w;
e[i]={a, b, w};
}
bellman_ford();
//为什么是>=MAX/2,
if(dis[n]>=MAX/2) cout<<"impossible";
else cout<<dis[n];
return 0;
}
–
总结
- 创建struct edge存储每条边
//创建edge存储每条边
struct Edge{
int a;
int b;
int w;
} e[M];
- 初始化距离矩阵和起点
- 遍历边数限制
- 备份距离数组
- 遍历所有路径段进行松弛操作,