Bellman-Ford算法实现类

貌似Bellman-Ford算法和Dijkstra算法类似,只是多了个处理负权值的考虑。不过Bellman-Ford算法比较简单易懂,虽然复杂度较高,有O(VE)。

算法类如下,至于介绍吧,维基(http://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm)上面蛮详细的。

三个步骤:

1、数组Distant[i]记录从源点s到顶点i的路径长度,初始化数组Distant[n]为无穷大, Distant[s]为0;
2、以下操作循环执行至多n-1次,n为顶点数:
对于每一条边e(u, v),如果Distant[u] + w(u, v) < Distant[v],则另Distant[v] = Distant[u]+w(u, v)。w(u, v)为边e(u,v)的权值;
若上述操作没有对Distant进行更新,说明最短路径已经查找完毕,或者部分点不可达,跳出循环。否则执行下次循环;
3、为了检测图中是否存在负环路,即权值之和小于0的环路。对于每一条边e(u, v),如果存在Distant[u] + w(u, v) < Distant[v]的边,则图中存在负环路,即是说改图无法求出单源最短路径。否则数组Distant[n]中记录的就是源点s到各顶点的最短路径长度。

#include <iostream>

#define POINTNUM 10
#define NOSET_POSITIVE_INT -1
#define INIFINITE 2147483647

using namespace std;

struct Edge 
{
	int source;
	int destination;
	int weight;
};

class Graph
{
public:
	Edge graphEdge[POINTNUM * POINTNUM];
	int edgeNum;
	int pointNum;
	int source;
	int destination;

	int distance[POINTNUM];

	Graph();
	bool BellmanFord();

private:
	void initialize();				//Initialize the variables.
	void relaxEdges();				//Relax the edges.
	bool checkNegativeCycle();		//Check negative weight cycles.
};

Graph::Graph()
{
	edgeNum = 0;
	pointNum = 0;
	source = NOSET_POSITIVE_INT;
	destination = NOSET_POSITIVE_INT;
}

void Graph::initialize()
{
	for (int i = 0; i < pointNum; i++)
	{
		distance[i] = INIFINITE;
	}

	distance[source] = 0;
}

void Graph::relaxEdges()
{
	unsigned int a;
	unsigned int b;

	for (int i = 1; i < pointNum; i++)
	{
		for (int j = 0; j < edgeNum; j++)
		{
			a = (unsigned int)distance[graphEdge[j].source] + (unsigned int)graphEdge[j].weight;
			b = (unsigned int)distance[graphEdge[j].destination];

			if (a < b)
			{
				distance[graphEdge[j].destination] = a;
			}
		}
	}
}

bool Graph::checkNegativeCycle()
{
	unsigned int a;
	unsigned int b;

	for (int i = 0; i < edgeNum; i++)
	{
		a = (unsigned int)distance[graphEdge[i].source] + (unsigned int)graphEdge[i].weight;
		b = (unsigned int)distance[graphEdge[i].destination];

		if (a < b)
		{
			return false;
		}
	}

	return true;
}

bool Graph::BellmanFord()
{
	initialize();

	relaxEdges();

	return checkNegativeCycle();
}

int main()
{
	Graph a;
	cin >> a.edgeNum;
	cin >> a.pointNum;

	for (int i = 0; i < a.edgeNum; i++)
	{
		cin >> a.graphEdge[i].source >> a.graphEdge[i].destination >> a.graphEdge[i].weight;
	}

	cin >> a.source;

	if( a.BellmanFord() )
	{
		for (int i = 0; i < a.pointNum; i++)
		{
			cout << "Distance: " << a.distance[i] << endl;
		}
	}

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值