贝尔曼福特算法
Posted sxq-study
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贝尔曼福特算法相关的知识,希望对你有一定的参考价值。
有边数限制,存在负权值,的最短路问题,一般用bellmanford算法:
给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数。
请你求出从1号点到n号点的最多经过k条边的最短距离,如果无法从1号点走到n号点,输出impossible。
注意:图中可能 存在负权回路 。
输入格式
第一行包含三个整数n,m,k。
接下来m行,每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。
输出格式
输出一个整数,表示从1号点到n号点的最多经过k条边的最短距离。
如果不存在满足条件的路径,则输出“impossible”。
数据范围
1≤n,k≤5001≤n,k≤500,
1≤m≤100001≤m≤10000,
任意边长的绝对值不超过10000。
输入样例:
3 3 1
1 2 1
2 3 1
1 3 3
输出样例:
3
########################################################################
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N = 510, M = 1e4+10; 5 6 struct edge{ 7 int a, b, w;//从a指向b权值为w的边 8 }edges[M]; 9 10 vector<int> dist(N, 0x3f3f3f3f); 11 vector<int> last(N, 0x3f3f3f3f);//备份数组 12 int n, m; 13 int k; 14 15 int bellmanford(){ 16 dist[1] = 0; 17 //加备份数组代表最短路径边数小于等于k, 不加代表大于等于k 18 for(int i = 0;i < k;++i){ 19 last = dist; 20 for(int j = 0;j < m;++j){ 21 auto t = edges[j]; 22 dist[t.b] = min(dist[t.b], last[t.a] + t.w); 23 } 24 } 25 return dist[n] > 0x3f3f3f3f/2 ? -1 : dist[n];//这里取一半是因为正无穷加上一个负权值比正无穷小了,但是不至于小到不足一半 26 } 27 28 int main(){ 29 cin >> n >> m >> k; 30 for(int i = 0;i < m;++ i){ 31 int x, y, z; 32 cin >> x >> y >> z; 33 edges[i] = {x, y, z}; 34 } 35 int t = bellmanford(); 36 if(t == -1) cout << "impossible" <<endl; 37 else cout << t << endl; 38 return 0; 39 }
end
以上是关于贝尔曼福特算法的主要内容,如果未能解决你的问题,请参考以下文章
算法入门之完美单源最短路径:Bellman-Ford(贝尔曼-福特)算法