Bellman-Ford求单源最短路(不能存在负圈)复杂度O(|V|*|E|)

以这个图为例:
无向图

输入:
第一行两个整数V(顶点数)和E(边数)
下面有E行,每行三个数,表示相连的顶点以及边的长度(这里是无向图)

7 10
1 2 2
1 3 5
2 5 10
2 4 6
2 3 4
3 4 2
4 6 1
5 6 3
5 7 5
6 7 9

注意:
核心代码:

if (dis[e.from] != inf && dis[e.to] > dis[e.from] + e.cost) {
    
    
    dis[e.to] = dis[e.from] + e.cost;
    update = true;
}

就是说,如果从s到e.to的距离要大于经过e这条边到e.to的距离时,更新长度
然后一直while循环,知道update = false为止

Code:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int inf = 0x3f3f3f3f;
const int maxn = 10007;

struct edge {
    
    
    int from, to, cost;
};

edge es[maxn];
int V, E;
int dis[maxn];
void shortest_path(int s) {
    
    
    for (int i=1;i<=V;i++) {
    
    
        dis[i] = inf;
    }
    dis[s] = 0;
    while (true) {
    
    
        bool update = false;
        for (int i=0;i<2*E;i++) {
    
    //到2*E是因为是无向图
            edge e = es[i];
            if (dis[e.from] != inf && dis[e.to] > dis[e.from] + e.cost) {
    
    
                dis[e.to] = dis[e.from] + e.cost;
                update = true;
            }
        }
        if (!update)  break;
    }
}
int main()
{
    
    
    scanf("%d %d", &V, &E);
    int from, to, cost;
    for (int i=0;i<2*E;i++) {
    
    //到2*E是因为是无向图
        scanf("%d %d %d", &from, &to, &cost);
        es[i] = edge {
    
    from, to, cost};

        es[++i] = edge {
    
    to, from, cost};
    }
    shortest_path(1);//计算1到各顶点的距离,结果保存在dis数组里面
    for (int i=1;i<=V;i++) {
    
    
        printf("%d ", dis[i]);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/u010017231/article/details/108818704
今日推荐