在学习这个算法之前,相信大家都已经学习过dijkstra算法了,如果大家还看过别的关于bellman-ford算法的文章,那些文章一定讲过dijkstra算法无法解决存在负权环的图的单源最短路问题。那么我们先来看看为什么dijkstra算法不行
如果我们采用dijkstra算法来求这个图的单源最短路径
经过四次松弛之后,我们认为最短路已经求出来了,其实不然。注意到图中存在2,3结点这个负权环,其实3结点的dis可以无限的的减小。而采用bellman-ford算法,对于存在负权环的图该算法可以"检测"出来。
下面我们开始讲解bellman-ford算法
这个算法的大致思想是
下面贴一下代码
#include <iostream> using namespace std; const int MAX = 1001; const int INF = 0x3fffffff; struct { int u,v,dis; }edge[MAX]; int dis[MAX]; int root[MAX]; bool bellman_ford(int nodenum,int start,int edgenum) { for(int i=1;i<=nodenum;i++) dis[i] = INF; dis[start] = 0; for(int i=1;i<nodenum;i++)//如果不存在负权环,则在nodenum-1次循环后最短路必求出来 { for(int j=1;j<=edgenum;j++)//松弛每一条边 { if(dis[edge[j].v]>dis[edge[j].u]+edge[j].dis) { dis[edge[j].v] = dis[edge[j].u]+edge[j].dis; root[edge[j].v] = edge[j].u; } } } bool flag = true; for(int j=1;j<=edgenum;j++) //检查有无负权环 { if(dis[edge[j].v]>dis[edge[j].u]+edge[j].dis) { flag = false; break; } } return flag; }