Bellman-Ford求单源最短路径

思路:Bellman-Ford解决的是带权有向图的单源最短路径问题。图中可以存在负权值的边,而且有负环时可以检测出来。设图中共有v个结点,e条边。算法分为以下三步。1.初始化所有结点的前驱结点为-1(不存在),初始化所有结点的最短路径权值为INF(无穷大),将源点的最短路径权值设为0。2.对图中所有边进行v-1次松弛操作。3.如果图中还有边可以进行松弛,则表示有负环存在,返回false。所谓的松弛操作是指,对于边(u,v),如果dis[v]>dis[u]+w(u,v),则dis[v]=dis[u]+w(u,v)。其中dis表示最短路径权值,w表示边的权值。

代码:

// bellman_ford.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <fstream>
#include <stack>

#define MAX 100
#define INF 1000000

using std::cin;
using std::cout;
using std::endl;
using std::cerr;
using std::vector;
using std::ifstream;
using std::stack;

typedef struct Edge {
	int u;
	int v;
	int val;
};

//对边(u,v)的松弛操作
void relax(int u, int v, int dis[MAX], int pre[MAX], Edge edge[MAX], int index)
{
	if (dis[v] > dis[u] + edge[index].val)
	{
		dis[v] = dis[u] + edge[index].val;
		pre[v] = u;
	}
}

bool bellman_ford(Edge edge[MAX], int vertex_num, int edge_num, int dis[MAX], int pre[MAX])
{
	//n-1次松弛操作
	for (int i = 0; i < vertex_num - 1; i++)
		for (int j = 0; j < edge_num; j++)
			relax(edge[j].u, edge[j].v, dis, pre, edge, j);

	for (int i = 0; i < edge_num; i++)
		if (edge[i].v > edge[i].u + edge[i].val)
			return false;

	return true;
} 

//重构路径
void reconstruct(int i, int pre[MAX], stack<int> &s)
{
	if (pre[i] == -1) //边界情况,重构源结点
	{
		s.push(i);
		return;
	}

	s.push(i); //加入本结点
	while(pre[i]!=-1)
	{
		s.push(pre[i]);
		i = pre[i];
	}
	
}

int main()
{
	ifstream in;
	in.open("bellman_ford测试数据.txt");

	int vertex_num, edge_num; //点数,边数
	in >> vertex_num >> edge_num;

	Edge edge[MAX];

	int u, v, val;
	for (int i = 0; i < edge_num; i++)
	{
		in >> u >> v >> val;
		edge[i].u = u;
		edge[i].v = v;
		edge[i].val = val;
	}

	int dis[MAX]; //最短路径权重
	for (int i = 0; i < vertex_num; i++)
		dis[i] = INF;

	int pre[MAX]; //前驱结点
	for (int i = 0; i < vertex_num; i++)
		pre[i] = -1;

	dis[0] = 0;

	bellman_ford(edge, vertex_num, edge_num, dis, pre);

	stack<int> s; //用于重构路径

	for (int i = 0; i < vertex_num; i++)
	{
		cout << dis[i] << endl << "route: ";
		
		reconstruct(i, pre, s);
		while (!s.empty())
		{
			int temp = s.top();
			cout << temp << " ";
			s.pop();
		}
		cout << endl;
	}

	system("pause");
	return 0;
}

运行结果:

《Bellman-Ford求单源最短路径》

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