单源最短路径算法涉及到松弛技术。 对于每个结点v来说,我们用一个属性p(v)来记录,从源节点
到节点v的最短路径权重的上界,称此属性为s到v的最短 路径估计。
松弛操作
对一条边(u,v)来说,在边(u,v)上的松弛操作为, 比较p(v)与p(u)加上边(u,v)的权重。如果当前最短路
径权重上界大于新值,则更新,最短路径估计。 以节点数为5的图,源节点为0为例,如图所示
松弛操作C代码
void relax(int u,int v,graphpoint g,int x)
{
if(cost[x][v] > cost[x][u] + value[u][v])
{
cost[x][v] = cost[x][u] + value[u][v];
g[v].parent = u;
}
}
x用传入源节点 u,v表示待松弛的边,cost数组存取权重估计值,每个
节点的parent属性更新路径上的上一个节点。 bellman-ford算法对每个节点进行初始化然后进行v-1次松弛操作,以
求解出最短路径。 v-1次可以保证每个节点的所有边都被松弛,一个节点
不会有超过v-1条边。
Bellman-Ford算法C代码
void mincost(graphpoint g,int post,int (*cost)[5])
{
void relax(int a,int b,graphpoint c,int d);
int i,j,m = 0;
for(i = 0;i<5;i++)
for(j = 0;j<5;j++)
{
cost[i][j] = 1000;
}
cost[0][0] = 0;
for(i = 0;i < 4;i++)
{
for(j = 0;j < 5;j++)
{
m = 0;
while(g[j].next[m] != -1)
{
relax(j,g[j].next[m],g,0);
m++;
}
}
}
}
完整代码C语言
#include<stdio.h>
#include<malloc.h>
#include<memory.h>
int value[5][5]; //权重
int cost[5][5]; //估值
typedef struct{
int post;
int data;
int next[5];
int parent;
}graph,*graphpoint;
void initgraph(graphpoint g) //初始化图(忽略这粗糙的初始化过程(lll¬ω¬))
{
int i;
for(i = 0;i<5;i++)
{
g[i].data = i+1;
g[i].post = i;
memset(g[i].next,-1,sizeof(g[i].next));
}
g[0].next[0] = 1,g[0].next[1] = 4;
g[1].next[0] = 2,g[1].next[1] = 3,g[1].next[2] = 4;
g[2].next[0] = 0,g[2].next[1] = 3;
g[3].next[0] = 2;
g[4].next[0] = 1,g[4].next[1] = 3;
value[0][4] = 3,value[0][1] = 5;
value[1][2] = 6,value[1][3] = 4,value[1][4] = 1;
value[2][0] = 3,value[2][3] = 7;
value[3][2] = 2;
value[4][1] = 2,value[4][3] = 6;
}
void showgraph(graph g[]) //打印图
{
int i,j,m = 0;
for(i = 0;i<5;i++)
{
printf("%d",i);
while(g[i].next[m] != -1)
{
printf("->%d",g[i].next[m]);
m++;
}
m = 0;
printf("\n");
}
}
void mincost(graphpoint g,int post,int (*cost)[5]) //BELLMAN
{
void relax(int a,int b,graphpoint c,int d);
int i,j,m = 0;
for(i = 0;i<5;i++)
for(j = 0;j<5;j++)
{
cost[i][j] = 1000;
}
cost[0][0] = 0;
for(i = 0;i < 4;i++)
{
for(j = 0;j < 5;j++)
{
m = 0;
while(g[j].next[m] != -1)
{
relax(j,g[j].next[m],g,0);
m++;
}
}
}
}
void relax(int u,int v,graphpoint g,int x) //松弛操作
{
if(cost[x][v] > cost[x][u] + value[u][v])
{
cost[x][v] = cost[x][u] + value[u][v];
g[v].parent = u;
}
}
int main()
{ int n;
printf("输入终点:\n");
scanf("%d",&n);
graph g[5];
initgraph(g);
showgraph(g);
mincost(g,0,cost);
printf("最小权重为\n");
printf("%d\n",cost[0][n]);
printf("路径为\n");
while(g[n].post != 0)
{
printf("%d<-",g[n].post);
n = g[n].parent;
}
printf("%d",0);
}
运行实例 编译器DEV C++