# 数据结构与算法C++之单源最短路径算法 Bellman-Ford

``````#include <iostream>
#include "SparseGraph.h"
#include "BellmanFord.h"

using namespace std;

int main() {

string filename = "testG2.txt";
//string filename = "testG_negative_circle.txt";
int V = 5;

SparseGraph<int> g = SparseGraph<int>(V, true);

cout<<"Test Bellman-Ford:"<<endl<<endl;
BellmanFord<SparseGraph<int>, int> bellmanFord(g,0);
if( bellmanFord.negativeCycle() )
cout<<"The graph contain negative cycle!"<<endl;
else
for( int i = 1 ; i < V ; i ++ ){
cout<<"Shortest Path to "<<i<<" : "<<bellmanFord.shortestPathTo(i)<<endl;
bellmanFord.showPath(i);
cout<<"----------"<<endl;
}

return 0;
}
``````

BellmanFord.h定义为

``````#include <stack>
#include <vector>

#ifndef _EDGE_H_
#define _EDGE_H_
#include "Edge.h"
#endif

using namespace std;

template <typename Graph, typename Weight>
class BellmanFord{

private:
Graph &G;
int s;
Weight* distTo;
vector<Edge<Weight>*> from;
bool hasNegativeCycle;

bool detectNegativeCycle(){

for( int i = 0 ; i < G.V() ; i ++ ){
if( !from[e->w()] || distTo[e->v()] + e->wt() < distTo[e->w()] )
return true;
}

return false;
}

public:
BellmanFord(Graph &graph, int s):G(graph){

this->s = s;
distTo = new Weight[G.V()];
for( int i = 0 ; i < G.V() ; i ++ ){
from.push_back(NULL);
}

// Bellman-Ford
distTo[s] = Weight();

for( int pass = 1 ; pass < G.V() ; pass ++ ){

// Relaxation
for( int i = 0 ; i < G.V() ; i ++ ){
if( !from[e->w()] || distTo[e->v()] + e->wt() < distTo[e->w()] ){
distTo[e->w()] = distTo[e->v()] + e->wt();
from[e->w()] = e;
}
}
}

hasNegativeCycle = detectNegativeCycle();
}

~BellmanFord(){

delete[] distTo;
}

bool negativeCycle(){
return hasNegativeCycle;
}

Weight shortestPathTo( int w ){
assert( w >= 0 && w < G.V() );
assert( !hasNegativeCycle );
return distTo[w];
}

bool hasPathTo( int w ){
assert( w >= 0 && w < G.V() );
return from[w] != NULL;
}

void shortestPath( int w, vector< Edge<Weight> > &vec ){

assert( w >= 0 && w < G.V() );
assert( !hasNegativeCycle );

stack<Edge<Weight>*> s;
Edge<Weight> *e = from[w];
while( e->v() != this->s ){
s.push(e);
e = from[e->v()];
}
s.push(e);

while( !s.empty() ){
e = s.top();
vec.push_back( *e );
s.pop();
}
}

void showPath(int w){

assert( w >= 0 && w < G.V() );
assert( !hasNegativeCycle );

vector< Edge<Weight> > vec;
shortestPath(w, vec);
for( int i = 0 ; i < vec.size() ; i ++ ){
cout<<vec[i].v()<<" -> ";
if( i == vec.size()-1 )
cout<<vec[i].w()<<endl;
}
}
};
``````

“testG2.txt”

``````5 8
0 1 5
0 2 2
0 3 6
1 2 -4
1 4 2
2 4 5
2 3 3
4 3 -3
``````

``````5 9
0 1 5
0 2 2
0 3 6
1 2 -4
2 1 1
1 4 2
2 4 5
2 3 3
4 3 -3
``````

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