上一篇博文中,作者总结了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");
}