算法-图论-最短路径-BellmanFord算法
处理含有负权环的图
#include <iostream> #include <vector> #include <stack> #include "Edge.h" #include "IndexMinHeap.h" using namespace std; template<typename Graph,typename Weight> class BellmanFord { private: Graph &G; int s;//源 Weight *distTo;//距离 vector<Edge<Weight>*> from;//最短路径是谁 bool hasNegativeCycle; bool detectNegetiveCycle(){ for(int i=0;i<G.V();i++){ typename Graph::adjIterator adj(G,i); for(Edge<Weight>* e = adj.begin();!adj.end();e = adj.next()){ if(!from[e->w()] || dist[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); }; //BellmanFord distTo[s] =Weight(); for(int pass =1;pass<G.V();pass++){ //松弛操作 for(int i=0;i<G.V();i++){ typename Graph::adjIterator adj(G,i); for(Edge<Weight>* e = adj.begin();!adj.end();e = adj.next()){ if(!from[e->w()] || dist[e->v()] +e->wt() < distTo[e->w()]){ distTo[e->w()] = distTo[e-v()] + e->wt(); from[e->w()] =e; } } } } hasNegativeCycle = detectNegetiveCycle(); }; ~BellmanFord(){ delete[] distTo; }; bool negetiveCycle(){ 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 marked[w]; } 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() != e->w()) { s.push(e); e = from[e->v()]; } 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++){ count<<vec[i].v()<<" ->"; if(i==vec.size()-1) count<<vec[i].w()<<endl; } } };