算法储备之Bellman-Ford算法

Bellman-Ford算法也是求图的单源点最短路径问题。

不同于Dijkstra算法的是它能应用于带负权值边的图,并且可以判断图中是否有负循环。

该算法的时间复杂度为O(VE) more than Dijkstra算法。

V为顶点个数

dist[V]数组记录所有顶点到源点的距离

执行V-1次循环

  每次循环对每一条边执行如下操作

    if(dist[v]>dist[u]+weight of edge uv)

      dist[v]=dist[u]+weight;

执行第V次以上操作,若dist数组有改动则图中有负循环

#include <iostream>
#include <vector>

using namespace std;

struct Edge {
	int src, dest, weight;
	Edge(int s, int d, int w) : src(s), dest(d), weight(w) { }
};
struct Graph {
	int V;
	vector<Edge> edge;
public:
	Graph(int v) : V(v) { }
	void addEdge(int src, int dest, int weight);
	void BellmanFord(int src);
};

void Graph::addEdge(int src, int dest, int weight)
{
	edge.push_back(Edge(src, dest, weight));
}

void printSolution(vector<int> & dist)
{
	cout << "Vertex   Distance from Source" << endl;
	for (int i = 0;i < dist.size();i++)
		cout << i << "\t\t" << dist[i] << endl;
}

void Graph::BellmanFord(int src)
{
	vector<int> dist(V, INT_MAX);
	dist[src] = 0;

	for (int i = 1;i < V;i++)
	{
		for (Edge e : edge)
		{
			int u = e.src;
			int v = e.dest;
			int weight = e.weight;
			if (dist[u] != INT_MAX && dist[u] + weight < dist[v])
				dist[v] = dist[u] + weight;
		}
	}

	for (Edge e : edge)
	{
		int u = e.src;
		int v = e.dest;
		int weight = e.weight;
		if (dist[u] != INT_MAX && dist[u] + weight < dist[v])
		{
			cout << "Graph contains negetive weight cycle" << endl;
			break;
		}
	}
	printSolution(dist);

	return;
}

int main()
{

	Graph graph(5);

	graph.addEdge(0, 1, -1);
	graph.addEdge(0, 2, 4);
	graph.addEdge(1, 2, 3);
	graph.addEdge(1, 3, 2);
	graph.addEdge(1, 4, 2);
	graph.addEdge(3, 2, 5);
	graph.addEdge(3, 1, 1);
	graph.addEdge(4, 3, -3);

	graph.BellmanFord(3);

	return 0;
}

   

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