Bellman–Ford算法与Dijkstar算法一样都是解决单源最短路径的问题;都是通过对节点的松弛操作来实现最短路径的求解,不同的是,Dijkstar算法是通过贪心思想,每次加入一个最小距离的顶点,来完成对节点的松弛操作,而Bellman–Ford算法则是简单的对所有边进行松弛操作,共|V | − 1次,其中 |V |是图的点的数量。
Bellman–Ford代码
代码使用邻接表实现图
#define MAXNUM 65536
struct {
int dist; //记录距离
int path; //记录路径
}table[MAXVERTEX]; //记录信息的表
void BellmanFord(Graph G,int s) {
//已图G中顶点s为源点,求解最短路径
int i,v, e;
ptrNode p;
for (i = 0; i < G->Nv; i++) {
//初始化距离和路径
table[i].dist = MAXNUM;
table[i].path = -1;
}
table[s].dist = 0; //到自身的距离为0
for (v = 0; v <= G->Nv - 1;v++) { //做N-1次对所有边的松弛
for (i = 0; i < G->Nv;i++) {
for (p = G->G[i].first;p; p = p->next) {
//如果有一个顶点w,使得顶点v的路径更小,则更新
if (table[p->v].dist > table[i].dist + p->weight) {
table[p->v].dist = table[i].dist + p->weight;
table[p->v].path = i;
}
}
}
}
int flag = 1;
for (i = 0; i < G->Nv; i++) { //再对所有边做一次松弛
for (p = G->G[i].first; p; p = p->next) {
//若还能进行松弛操作,则说明存在负值回路
if (table[p->v].dist > table[i].dist + p->weight) {
flag = 0; //标记
break; //退出
}
}
}
if (flag == 0) {
//存在回路
printf("存在负值回路\n");
}
else {
//不存在回路
printf("求解完成\n");
}
}