Bellman-Ford算法图解

一、Bellman-Ford算法用到的“材料”:

1、一个结果数组dis,这个结果数组记录从源点到其他点的最短距离,如dis[10] 表示(加入开始节点标号为1)开始节点1到10号节点的最短距离。

2、C/C++中定义结构体Edge,表示边,内设变量from、to、cost,分别表示这条边的开始标号、终点标号、边长度

3、为了方便测验设置一个边的数组,C++定义:Edge edges[100];

二、Bellman-Ford算法图解

如图所示,针对一般情况分析,对一条边来说,我们想更新数组dis,让dis[i]变成从源点start到编号为index的点的最小值,所以就上图来说,当我们选择一条边e,如果start到e.from的距离可以估计(不是INF),那么start到to节点的距离就可以知道了,如果在之前dis[e.to]已经被更新过了,那么就要判断从start到e.from的距离加上e.cost的值 是否 小于 dis[e.to] 的值,如果小于就更新dis[e.to] = dis[e.from] + e.cost ,如果不是,那么就继续循环或跳出。

三、示例代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#define INF 0x7fffffff
using namespace std;

const int N = 100;
typedef struct Edge{
    int from;
    int to;
    int cost;
}Edge;

int dis[N];
Edge edges[N];
void init(int n,int st){
    for(int i = 0 ;i <= n; ++i){
        dis[i] = INF ;
    }
    dis[st] = 0 ;
}

void BellmanFord(int n, int m){
    while(true){
        bool update = false;  //如果某一次循环没有更新dis数组,那么就代表这个图遍历完成了。时间复杂度O(V * E)

        for(int i = 0 ; i < m; ++i){
            Edge e = edges[i];

            if(dis[e.from] != INF && dis[e.from] + e.cost < dis[e.to]){
                dis[e.to] = dis[e.from] + e.cost;
                update = true;
            }
            if(dis[e.to] != INF && dis[e.to] + e.cost < dis[e.from]){
                dis[e.from] = dis[e.to] + e.cost;
                update = true;
            }
        }
        if(!update){
            break;
        }
    }
}
void prt(int n){
    for(int i = 1; i<= n; ++ i){
        printf("%d ",dis[i]);
    }
    cout<<endl;
}
int main(){
    int n , m;    //n个顶点,m条边
    while(cin>>n>>m){
        init(n , 1);
        for(int i = 0 ; i< m ;++i){
            cin>>edges[i].from>>edges[i].to>>edges[i].cost;
        }

        BellmanFord(n , m);
        prt(n);
    }
    return 0;
} 

/*
测试
7 10
1 2 2
1 3 5
2 3 4
3 4 2
2 4 6
2 5 10
5 6 3
4 6 1
6 7 9
5 7 5
*/

原文地址:https://www.cnblogs.com/dqsBK/p/8441110.html

时间: 2024-10-08 03:28:31

Bellman-Ford算法图解的相关文章

Bellman - Ford 算法解决最短路径问题

Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力不从心了,而Bellman - Ford算法可以解决这种问题. Bellman - Ford 算法可以处理路径权值为负数时的单源最短路径问题.设想可以从图中找到一个环路且这个环路中所有路径的权值之和为负.那么通过这个环路,环路中任意两点的最短路径就可以无穷小下去.如果不处理这个负环路,程序就会永远运

Bellman—Ford算法思想

---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G运行Bellman—Ford算法的结果是一个布尔值,表明图中是否存在着一个从源点s可达的负权回路.若存在负权回路,单源点最短路径问题无解:若不存在这样的回路,算法将给出从源点s到图G的任意顶点v的最短路径值d[v] Bellman—Ford算法流程 分为三个阶段: (1)初始化:将除源点外的所有顶点

poj 3259 Wormholes (BELLman—FOrd算法)(邻接矩阵表示)

http://poj.org/problem?id=3259 之前一开始 ,没做出来,搁置了好几天才看见bug所在.所以今天a掉了 ,把代码贴出来,这个使用邻接矩阵表示的 ,下一篇用邻接表可以提高效率. #include<iostream> #include<queue> #include<stdio.h> #include<string.h> using namespace std; const int INF=600; int G[INF][INF];

最短路径——Bellman Ford算法(C++)

源代码: #include<cstdio>#include<cstring>int m(1),n,k,i[1001],x[1001],y[1001],f[1001];int main(){ scanf("%d%d",&n,&k); for (int a=1;a<=n;a++) for (int b=1;b<=n;b++) { scanf("%d",&i[m]); if (i[m]!=-1) { x[m]=a

POJ 1860 Currency Exchange (Bellman ford)

Currency Exchange Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22405   Accepted: 8095 Description Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and pe

bellman-ford算法

给定图G(V, E)(其中V.E分别为图G的顶点集与边集),源点s, 数组Distant[i]记录从源点s到顶点i的路径长度,初始化数组Distant[n]为, Distant[s]为0: 以下操作循环执行至多n-1次,n为顶点数:对于每一条边e(u, v),如果Distant[u] + w(u, v) < Distant[v],则另Distant[v] = Distant[u]+w(u, v).w(u, v)为边e(u,v)的权值:若上述操作没有对Distant进行更新,说明最短路径已经查找完

ACM/ICPC 之 最短路径-Bellman Ford范例(POJ1556-POJ2240)

两道Bellman Ford解最短路的范例,Bellman Ford只是一种最短路的方法,两道都可以用dijkstra, SPFA做. Bellman Ford解法是将每条边遍历一次,遍历一次所有边可以求得一点到任意一点经过一条边的最短路,遍历两次可以求得一点到任意一点经过两条边的最短路...如 此反复,当遍历m次所有边后,则可以求得一点到任意一点经过m条边后的最短路(有点类似离散数学中邻接矩阵的连通性判定) POJ1556-The Doors 初学就先看POJ2240吧 题意:求从(0,5)到

《算法图解》代码实现和改进

<算法图解>代码实现和改进 请随意观看表演 二分查找 数组和链表 递归 递归条件和基线条件 快速排序 散列表 广度优先搜索 狄克斯特拉算法 贪婪算法 二分查找 def bin_search(list,item): low = 0 high = len(list) - 1 while low<=high: mid = (low+high)//2 #得到中间值 guess = list[mid] if guess==item: return mid elif guess>item: h

《算法图解》示例代码的实现

这几天看了<算法图解>,把里面的示例代码都实现了一边,在 github 上找到了一位朋友的仓库,fork 了他的. 里面有我们添加的 Python,Java,C++的实现,欢迎大家 fork!!! 附上网址:https://github.com/lynxux/AlgorithmDiagram 原文地址:https://www.cnblogs.com/linkcode/p/8185994.html