贝尔曼福特算法

有边数限制,存在负权值,的最短路问题,一般用bellmanford算法:

给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数。

请你求出从1号点到n号点的最多经过k条边的最短距离,如果无法从1号点走到n号点,输出impossible。

注意:图中可能 存在负权回路 。

输入格式

第一行包含三个整数n,m,k。

接下来m行,每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。

输出格式

输出一个整数,表示从1号点到n号点的最多经过k条边的最短距离。

如果不存在满足条件的路径,则输出“impossible”。

数据范围

1n,k5001≤n,k≤500,
1m100001≤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 }
View Code



end

原文地址:https://www.cnblogs.com/sxq-study/p/12236249.html