算法思想(九)—— 最短路径

9-1 最短路径问题和松弛操作


算法思想(九)—— 最短路径_第1张图片
例如:路径规划,工作任务规划。

之前说讲过的广度优先遍历:
算法思想(九)—— 最短路径_第2张图片

  • 其实求出的是一个点(起点)到其他顶点的最短路径问题,通过BFS,得到了一棵树,这棵树就叫做最短路径树(shortest path tree):即所有顶点距离起始顶点的总权值最小(注意和上一章所讲的最小生成树的区别)
  • 求得这个最短路径树的答案,其实就是解决了一个**单源最短路径(Single Source Shortest Path)**问题
无权图的最短路径

算法思想(九)—— 最短路径_第3张图片

有权图的最短路径

算法思想(九)—— 最短路径_第4张图片

松弛操作Relaxation:最短路径求解的核心
当我们到达一个结点的时候,我们要尝试一下,从这个结点到其他结点所得到的路径长度是否比之前求过的不经过这个节点到其他节点所得到的路径短,如果更短,我们要更新原始节点到这个节点的路径信息。

9-2 Dijkstra算法


算法思想(九)—— 最短路径_第5张图片
Dijkstra单源最短路径算法:

  • 前提:图中不能有负权边
  • 复杂度:O(E log(V))

9-3 实现Dijkstra算法


//Dijkstra算法求最短路径
template<typename Graph,typename Weight>
class Dijkstra{
   

private:
    Graph &G;//图的引用
    int s;//起始点
    Weight *distTo;//distTo[i]存储从起始点s到i的最短路径长度
    bool *marked;//标记数组,在算法过程中标记节点i是否被访问
    vector<Edge<Weight>*> from;//form[i]记录最短路径中,到达i点的边是哪一条
                               //可以用来恢复整个最短路径
public:
    //构造函数,使用Dijkstra算法求最短路径
    Dijkstra(Graph &graph,int s):G(graph)
    {
   
        //算法初始化
        assert(s>=0 && s<G.V());
        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
        //对于起始点s进行初始化
        distTo[s]=Weight();
        marked[s]=true;
        from[s] = new Edge<Weight>(s,s,Weight());
        ipq.insert(s,distTo[s]);
        while(!ipq.isEmpty()){
   
            int v = ipq.extractMinIndex();

            //distTo[v]就是s到v的最短距离
            marked[v]=true;

            //对v的所有相邻节点进行更新
            //进行松弛操作
            typename Graph::adjIterator adj(G,v);
            for(Edge<Weight>* e = adj.begin();!adj.end();e = adj.next()){
   
                int w = e ->other(v);
                //如果从s点到w点的最短路径还没有找到
                if(!marked[w]){
   
                    //如果w点以前没有访问过
                    //或者访问过,但是通过当前的v点到w点距离更短,则进行更新
                    if(from[w]==NULL || distTo[v]+e->wt

你可能感兴趣的:(算法思想,图论,算法导论)