算法-图论-最短路径-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;
        }
    }
};

 

posted @ 2020-04-11 10:16  Erick-LONG  阅读(270)  评论(0编辑  收藏  举报