bellman-ford


bellman-ford

适用范围

  • 最短路->单源最短路->存在负权边
  • 不存在负权回路
  • 存在负权回路,但限制走的路径数

时间复杂度

$nm$

n为最大路径数, m为边数

原理

  • 最大路径数为n, 总边数为m
  • 两层循环,第一层遍历n次,第二层遍历m
  • 第二层循环每次更新dist的最短路径
  • 切记,每次使用上一次的结果与现dist比较更新最短路
  • 因本思路只用记录边数,不用把点连接起来,所以我们直接用结构体记录边即可
  • 另,因可能存在负权边,所以如果没有最短路径,dist[n]的答案也可能小于0x3f3f3f3f,最小最小dist[n]也不会小于0x3f3f3f3f / 2,所以我们用这个来判断是否有最小路径

    例题

    https://www.acwing.com/problem/content/855/

ACcode

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 501, M = 10010;

struct Edge
{
    int a, b, w;
}edges[M];

int last[N];
int dist[N];
int n, m, k;

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 = 1; j <= m; j ++)
        {
            auto x = edges[j];
            dist[x.b] = min(dist[x.b], last[x.a] + x.w);
        }
    }
}
int main()
{
    cin >> n >> m >> k;
    for (int i = 1; i <= m; i ++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        edges[i] = {a, b, c};
    }
    bellman_ford();
    if(dist[n] > 0x3f3f3f3f / 2) cout << "impossible" << endl;
    else cout << dist[n] << endl;
    
    return 0;
}

文章作者: scholar
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 scholar !
 上一篇
Floyd Floyd
图论
2021-11-25 scholar
下一篇 
Spfa Spfa
图论
2021-11-25 scholar
  目录