算法-图论-最短路径-Dijsktra算法

前提不能有负权边,同样借助最小索引堆实现

#include <iostream>
#include <vector>
#include <stack>
#include "Edge.h"
#include "IndexMinHeap.h"

using namespace std;

template<typename Graph,typename Weight>
class Dijkstra
{
private:
    Graph &G;
    int s;//

    Weight *distTo;//距离
    bool *marked;//标记
    vector<Edge<Weight>*> from;//最短路径是谁
public:
    Dijkstra(Graph &graph,int s):G(graph){
        this->s = s;
        distTo = new Weight[G.V()];
        marked = new bool[G.V()];
        for(int i =0;i<G.V();i++){
            distTo[i] = Weight();
            marked[i] = false;
            from.push_back(NULL);
        }
        IndexMinHeap<Weight> ipq(G.V());

        //Dijkstra
        distTo[s] = Weight();
        marked[s]= true;
        ipq.insert(s,distTo[s]);
        while (!ipq.isEmpty())
        {
            int v = ipq.extractMinIndex();
            //distTo[v]就是s到v的最短距离
            marked[v] =true;
            
            //松弛操作
            typename Graph::adjIterator adj(G,v);
            for(Edge<Weight>* e = adj.begin();!adj.end();e = adj.next()){
                int w = e->other(v);
                if(!marked[w]){
                    if(from[w] == NULL || distTo[v] + e->wt() < distTo[w]){
                        distTo[w] = distTo[v] + e->wt();
                        from[w] = e;
                        if(ipq.contain(w))
                            ipq.change(w,distTo[w])
                        else
                            ipq.insert(w,distTo[w]);
                    }
                }
            }
        }
        
        
    };
    ~Dijkstra(){
        delete[] distTo;
        delete[] marked;
    };
    Weight shortestPathTo(int w){
        return distTo[w];
    }
    bool hasPathTo(int w){
        return marked[w];
    }
    void shortestPath(int w,vector<Edge<Weight>> &vec){
        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());
        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 09:50  Erick-LONG  阅读(182)  评论(0编辑  收藏  举报