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;
}