图--单源最短路径 -Bellman Ford 算法(可以存在负权边的情况和负权回路)算法导论p362

 Bellman Ford 算法  可以存在负权边的情况下解决单源最短路问题和,当出现负权回路时返回布尔值0,不然,则返回1,并可以源点到各点输出最短路径

主要步骤:

1、建立图(连接矩阵);

2、运行Bellman Ford 算法:

            对各点初始化;

           对图中的每一条边进行先后松弛n-1次

           检测是否有回路:当出现d[v]>d[u]+w(u,v)时即存在负权回路

3、输出结果

#include<stdio.h>
#define MAX 1000000
#define maxsize 10001
int G[maxsize][maxsize];

typedef struct
{
	char ch; //节点字符
	int pre;//前驱
	int d; //距离
}Node;
Node V[maxsize];

void input(int n,int e)//节点和边的录入 及建立连接矩阵图G
{
	int i,j,find,weight,s,d;
	char ch1,ch2;
	printf("请输入图的顶点 第一个顶点默认为源点\n");
	for(i=0;i<n;i++)
	scanf("%c ",&V[i].ch);
	for(i=0;i<=n;i++)
		for(j=0;j<=n;j++)
		G[i][j]=MAX;

	for(i=1;i<=e;i++)
	{
		scanf("%c %c %d ",&ch1,&ch2,&weight);
		find=0;
		for(j=0;find<2&&j<n;j++)
			if(ch1==V[j].ch)
			{
				s=j;
				find++;
			}
			else if(ch2==V[j].ch)
			{
				d=j;
				find++;
			}
	    G[s][d]=weight;
	}
}

void INTIALIZE_SINGLE_SOURCE(int n)//各节点最短距离和前驱的初始化
{
	int i;
	for(i=0;i<n;i++)
	{
		V[i].d=MAX;
		V[i].pre=-1;
	}
	V[0].d=0;
}
	
void RELAX(int u,int v)//松弛
{
	if(V[v].d>V[u].d+G[u][v])
	{
		V[v].d=V[u].d+G[u][v];
		V[v].pre=u;
	}
}

int BELLMAN_FORD(int n)//BELLman ford 算法
{  
	int u,v,k;
	INTIALIZE_SINGLE_SOURCE(n);
	for(k=1;k<n;k++)   //对每条边都要松弛n-1次
		for(u=0;u<n;u++)
			for(v=0;v<n;v++)
				if(G[u][v]<MAX)
					RELAX(u,v);
	for(u=0;u<n;u++)//判断图中是否有负权回路
		for(v=0;v<n;v++)
			if(V[v].d>V[u].d+G[u][v])
				return 0;           //有回路返回布尔值0
			return 1;//没回路返回布尔值1
}

void printpath(int i)//路径输出
{
	if(V[i].pre==-1)
	{
		printf("%c->",V[i].ch);
		return ;
	}
	else
	{
		    printpath(V[i].pre);
			printf("-%c",V[i].ch);
	}
}

void print(int n,int flag)//输出
{
	int i;
	if(flag==0)
		printf("有回路\n");
	else
	{
		for(i=0;i<n;i++)
			if(V[i].pre!=-1)
			{
				printf("%d: ",V[i].d);
				printpath(i);
				printf("\n");				
			}
			else if(i==0)
				printf("%d %c\n",V[i].d,V[i].ch);
			else
				printf(" 无穷大 %c\n",V[i].ch);
	}
}

int main()
{   freopen("1.txt","r",stdin);
	int n,e,flag;
	printf("请输入图的顶点的个数n和边数e:\n");
	scanf("%d%d ",&n,&e);
	input(n,e);    //节点和边的录入 及建立连接矩阵图G
	flag=BELLMAN_FORD(n);  //BELLman ford 算法 有回路返回布尔值0,没回路返回布尔值1
	print(n,flag);//输出
	return 0;
}


		


测试数据

5 10
s t x y z
s t 6
s y 7
t y 8
t x 5
t z -4
y x -3
y z 9
z x 7
z s 2
x t -2
 

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