迪杰斯特拉算法

一. 概述

Dijkstra算法是求一个顶点到其余各顶点的最短路径算法-
迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略
每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止

二. 算法流程

  1. 建立图的存储结构(邻接矩阵/邻接表)
  2. 初始化图
  3. 初始化源点到各点路径长度
  4. 初始化当前访问顶点集合并将源点加入
  5. 贪心寻找下一个未入集合的最近节点
  6. 将该节点加入已经访问顶点集合
  7. 以该节点为媒介更新其他顶点距离(未访问)
  8. 重复567操作n-1次
  9. 返回结果

三. C++模板

vector<vector<int>> graph;//邻接矩阵
    Graph(int n, vector<vector<int>>& edges) {//初始化图
        graph.resize(n);
        for(auto &point:graph)
            point.resize(n,INT_MAX);//初始赋无穷远距离
        for(int i=0;i<edges.size();i++){
            int from = edges[i][0];
            int to = edges[i][1];
            int cost = edges[i][2];
            graph[from][to] = cost;
        }     
    }
    void addEdge(vector<int> edge) {//加入边
            int from = edge[0];
            int to = edge[1];
            int cost = edge[2];
            graph[from][to] = cost;
    }
获取起点到终点的最短路径长度
int shortestPath(int node1, int node2) {
        int n = graph.size();
        vector<bool> vis(n);
        vector<int> dis(n,INT_MAX/2);
        dis[node1] = 0;
        for(int times=0;times<n;times++){//最多遍历n次
            int cur = -1;
            for(int i=0;i<n;i++){//贪心找最小值
                if(vis[i]||dis[i]==INT_MAX/2) continue;//跳过已经选取的点和无法到达的点
                if(cur==-1||dis[i]<dis[cur]) cur = i;
            }
            if(cur==-1) return -1;//表示无法到达目标
            if(cur==node2) break; //找到目标直接跳出,此时dis[cur]即为最短路径,无需再更新
            vis[cur] = 1;
            //找到当前最近点后,根据最近点进行更新
            for(int i=0;i<n;i++){
                if(vis[i]||graph[cur][i]==INT_MAX/2) continue;//对应点已选取,或对应的边不存在,无需更新
                dis[i] = min(dis[i],dis[cur]+graph[cur][i]);
            }
        }
        return dis[node2]==INT_MAX/2?-1:dis[node2];
    }

四. 实例

1. 设计可以求最短路径的图类

2. 前往目标的最小代价

3. 修改图中的边权

posted @ 2023-04-16 04:06  失控D大白兔  阅读(72)  评论(0编辑  收藏  举报