Spfa算法+bellman_ford算法

首先列举一下最短路径的各种算法的运用场合。

单源最短路径:

1)dijkstra算法——无负权边,有向图、无向图

2)bellman_ford算法——负权边,但不能存在负权回路,有向图、无向图

3)Spfa算法——负权边,但不能存在负权回路,有向图、无向图

多源最短路径:

floyd算法——负权边,但不能存在负权回路,有向图、无向图

bellman_ford算法是利用松弛操作来求得最短路径,而Spfa算法是在bellman_ford算法的基础上加了队列优化,具体讲解可参考网上其它教程

下面是bellman_ford算法模型:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Max 110
#define Inf 100000010
struct Node{
	int from,to;
	int value;
}node[Max*Max];
int dis[Max];
int path[Max];
int n,m,num;
bool bellman_ford(int index){
	for(int i=1;i<=n;i++){
		path[i]=index;
		dis[i]=Inf;
	}
	dis[index]=0;
	for(int i=1;i<n;i++)
		for(int j=0;j<num;j++)
			if(dis[node[j].to]>dis[node[j].from]+node[j].value){
				dis[node[j].to]=dis[node[j].from]+node[j].value;
				path[node[j].to]=node[j].from;
			}
    for(int j=0;j<num;j++)
		if(dis[node[j].to]>dis[node[j].from]+node[j].value)
			return false;
	return true;
}
void Show_path(int index){
	while(true){
	if(index==path[index]){
		printf("%d\n",index);
		break;
	}
	printf("%d ",index);
	index=path[index];
	}
}
void Show_dis(){
	if(!bellman_ford(1))
		printf("exist nagetive circle\n");
	else{
		for(int i=1;i<=n;i++)
			if(dis[i]!=Inf){
				printf("the shortexst length is:%d\n",dis[i]);
				Show_path(i);
			}
	}
}
int main(){
	while(scanf("%d%d",&n,&m),n){
		int pivot=0;
		int temp=m;
		while(temp--){
			scanf("%d%d%d",&node[pivot].from,&node[pivot].to,&node[pivot].value);
			pivot++;
		}
		num=pivot;
	   // bellman_ford(1);
		Show_dis();
	}
	return 0;
}
			
		

下面是Spfa算法模型:

#include <stdio.h>
#include <stdlib.h>
#include <queue>
#define Max 110
#define Inf 100000010
using namespace std;
int dis[Max];
int trim[Max][Max];
int used[Max];
bool vis[Max];
int path[Max];
int n,m;

bool spfa(int index){
	queue<int> Que;
	memset(vis,0,sizeof(vis));
	memset(used,0,sizeof(used));
	for(int i=1;i<=n;i++){
		dis[i]=Inf;
		path[i]=index;
	}
	dis[index]=0;
	vis[index]=true;
	used[index]=1;
	Que.push(index);
	while(!Que.empty()){
		int point=Que.front();
		Que.pop();
		vis[point]=false;
		for(int i=1;i<=n;i++)
			if(trim[point][i]!=Inf && dis[i]>dis[point]+trim[point][i]){
				dis[i]=dis[point]+trim[point][i];
				path[i]=point;
				if(!vis[i]){
					vis[i]=true;
					used[i]++;
					Que.push(i);
					if(used[i]>=n)
						return false;
				}
			}
	}
	return true;
}
void Show_path(int index){
	while(true){
		if(index==path[index]){
			printf("%d\n",index);
			break;
		}
		printf("%d ",index);
		index=path[index];
	}
}
void Show_dis(){
	if(!spfa(1))
		printf("exist negative circle\n");
	else{
		for(int i=1;i<=n;i++)
			if(dis[i]!=Inf){
				printf("the shortest length is:%d\n",dis[i]);
				Show_path(i);
			}
	}
}
		
int main(){
	int i,j;
	int a,b,value;
	while(scanf("%d%d",&n,&m),n){
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
				trim[i][j]=Inf;
		for(i=1;i<=m;i++){
			scanf("%d%d%d",&a,&b,&value);
			trim[a][b]=value;
		}
	    Show_dis();
	}
	return 0;
}
			
			
    

测试数据:

5 6
1 2 1
2 3 3
1 3 -2
4 1 2
1 5 4
3 4 -1

结果:

5 6
1 2 1
2 3 3
1 3 -2
4 1 2
1 5 4
3 4 -1
exist negative circle

 

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