邻接链表单源最短路径Bellman-Ford算法C语言

单源最短路径算法涉及到松弛技术。 对于每个结点v来说,我们用一个属性p(v)来记录,从源节点

到节点v的最短路径权重的上界,称此属性为s到v的最短 路径估计。

松弛操作

对一条边(u,v)来说,在边(u,v)上的松弛操作为, 比较p(v)与p(u)加上边(u,v)的权重。如果当前最短路

径权重上界大于新值,则更新,最短路径估计。 以节点数为5的图,源节点为0为例,如图所示
《邻接链表单源最短路径Bellman-Ford算法C语言》

松弛操作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++

《邻接链表单源最短路径Bellman-Ford算法C语言》

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/jazrynwong/article/details/80613419
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞