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

 

發佈了209 篇原創文章 · 獲贊 20 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章