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