码迷,mamicode.com
首页 > 编程语言 > 详细

贝尔曼福特算法

时间:2020-01-27 17:20:53      阅读:85      评论:0      收藏:0      [点我收藏+]

标签:event   ram   main   element   lse   spl   包含   大于等于   name   

有边数限制,存在负权值,的最短路问题,一般用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

贝尔曼福特算法

标签:event   ram   main   element   lse   spl   包含   大于等于   name   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!