上一篇博文中,作者总结了Prim算法,但是Prim算法对于那些含有负权重的赋权图的求解是没有办法,那么则需要一种动态规划的办法来解决此问题。该算法由Bellman和Ford提出,故称为Bellman-Ford算法。该算法是一种动态规划的想法。
下面给出该算法。
针对下图的例子,我们编写C语言程序来进行求解。
图1
实现结果:
实现的C语言代码如下:
#include<stdio.h> int matrix[100][100]; int n,i,j,ini;//ini为初始下标 char temp[100]; void inputmatrix() { printf("请输入邻接矩阵的阶数:\n"); scanf("%d",&n); printf("请输入有向图的邻接矩阵(输入0代表无穷大):\n"); for(i=0;i<n;i++) { for(j=0;j<n;j++) scanf("%d",&matrix[i][j]); } printf("请输入需计算的起始点下标:\n"); scanf("%d",&ini); } void caculate(int n,int a[100][100]) { int k,t=0,t1,t2,min,j,w,flag=0,i;/*k,k1作为循环的次数,flag=1意味着可以继续循环,flag=0,跳出*/ int distance[100][100]={0}; int path[100][100] = {0};//初试为空,记录path for(i=0;i<n;i++) if(i!=ini-1) distance[0][i]=10000000;//初始化值,代表无穷大 for(i=0;i<n;i++) for(j=0;j<n;j++) path[i][j]=0; path[ini-1][0]=ini; for(k=1;k<n;k++) { int flag=1; for(j=0;j<n;j++) distance[k][j]=distance[k-1][j];//for 任意u<V,do 这个 for(i=0;i<n;i++) { for(j=0;j<n;j++) if(a[i][j]!=0&&i!=j&&(distance[k-1][i]+a[i][j])<distance[k][j]) /*寻找符合条件的数*/ { flag=0;//有更新,继续循环,无更新操作,跳出 t1=j; t2=i; distance[k][j]=distance[k-1][i]+a[i][j]; //保存路径 for(w=0;w<n;w++)//把t2的值加给t1,并且最后加上t1该点 { if(path[t2][w]!=0) path[t1][w]=path[t2][w]; else { path[t1][w]=t1+1; break; } } } } if(flag) break; } printf("\n\n----下面为Bellman-ford算法计算结果----\n\n",ini,i+1,distance[i]); for(i=0;i<n;i++) { if(distance[k][i]==10000000) { printf("点%d到点%d无最短路径!\n",ini,i+1); } else{ printf("点%d到点%d的最小距离:%d\n",ini,i+1,distance[k][i]); printf("其最短路径:"); for(j=0;j<n;j++) { if(path[i][j]!=0) { printf("v%d ",path[i][j]); } else break; }} printf("\n"); } } main() { inputmatrix(); caculate(n,matrix); system("pause"); }