当前位置: 首页 > news >正文

C++ 最短路Dijkstra

Dijkstra朴素算法特点:

非负边权

单源最短路

顶点数最好少于1000

少量数据结构知识和一点点的算法基础

算法描述:

第一步建图,任何算法都需要考虑,用啥结构来存储,这个算法我们采取领接矩阵来存储,有时候输入数据,所以需要对数据做一些处理,也就是把图建立起来的过程。

第二步辅助数组,对于图G=[V, E],源点为s,dist[i] 表示s到i的最短路径,visited[i]表示dist[i]是否确定(布尔值),即s到i的最短路径,是否已确定。

第三步初始化,所有节点的数据见下

dist[i] = ∞ (0 <= i < n)

visited[i] = false (0 <= i < n)

dist[s] = 0

第四步找距离最小的点,从所有的visited[i]为false的顶点中找到一个dist[i]值最小的,令x=i,并且标记visited[x]为true,如果找不到,算法结束

第五步更新其余点的距离,更新从x出发的,到达顶点y的最小距离为dist[y],dist[y] = min(dist[y], dist[x]+w(x,y))

第六步重复执行,回到第四步,继续计算距离最小值

代码分析:

第一步,初始化邻接矩阵

function initEdges(graph, n)

  for u -> (0, n-1)

    for v -> (0, n-1)

      graph[u][v] = inf

第二步,边的添加

function addEdge(graph, u, v, w)

  graph[u][v] = min(graph[u][v], w)

第三步,建图,根据题目给出的数据,调用addEdge

addEdge(graph, u1, v1, w1)

addEdge(graph, u2, v2, w2)

...

第四步,框架代码

function Dijkstra(graph, n, s, dist)

  visited[]

  DijsktraInit(n, s, visited, dist)

  while true

    u = DilsktraFindMin(n, visited, dist)

    if u == -1 return

    DijsktraUpdate(graph, n, u, visited, dist)

第五步,Dijsktra初始化

function DijsktraInit(n, s, visited, dist)

  for i -> (0, n-1)

    visited[i] = false

    dist[i] = inf

  dist[s] = 0

第六步 Dijsktra找最小距离

function DijsktraFindMin(n, visited, dist)

  u = -1

  for i-> (0, n-1)

    if visited[i] continue

    if u == -1 or dist[i] < dist[u]

      u = i

return u

第七步,Dijsktra更新

function DilsktraUpdate(graph, n, u, visited, dist)

  visited[u] = true

  for i -> (0, n-1)

    if visited[i] continue

     dist[i] = min(dist[i], dist[u] + graph[u][i])

代码练习 1 对应力扣 网络延迟时间,代码见下

#define maxn 101
#define edgeType int
#define inf INT_MAX
class Solution {edgeType graph[maxn][maxn];void initEdge(int n){for(int i = 0; i < n; ++i){for(int j = 0; j < n; ++j){graph[i][j] = inf;}}}void addEdge(int u, int v, edgeType w){if(graph[u][v] == inf || w < graph[u][v]){graph[u][v] = w;}}void dijkstra(int n, int s, edgeType dist[maxn]){bool visited[maxn];for(int i=0; i<n; ++i){visited[i] = false;dist[i] = inf;}dist[s] = 0;while(1){edgeType minDist = inf;int minIndex;for(int i=0; i<n; ++i){if(visited[i]){continue;}if(minDist == inf || dist[i] < minDist){minDist = dist[i];minIndex = i;}}if(minDist == inf){break;}visited[minIndex] = true;for(int i=0; i<n; ++i){if(visited[i]){continue;}int dis = graph[minIndex][i];if(dis == inf){continue;}if(dist[i] == inf || dist[minIndex] + dis < dist[i]){dist[i] = dist[minIndex] + dis;}}}}
public:int networkDelayTime(vector<vector<int>>& times, int n, int k) {initEdge(n);for(int i=0; i<times.size(); ++i){int u = times[i][0] - 1;int v = times[i][1] - 1;edgeType w = times[i][2];addEdge(u, v, w);}edgeType dist[maxn];dijkstra(n, k-1, dist);int max = 0;for(int i=0; i<n; ++i){if(dist[i] == inf){return -1;}if(dist[i] > max){max = dist[i];}}return max;}
};

代码练习2 阈值距离内邻居最少的城市,代码见下

#define maxn 101
#define edgeType int
#define inf INT_MAX
class Solution {edgeType graph[maxn][maxn];void initEdge(int n){for(int i = 0; i < n; ++i){for(int j = 0; j < n; ++j){graph[i][j] = inf;}}}void addEdge(int u, int v, edgeType w){if(graph[u][v] == inf || w < graph[u][v]){graph[u][v] = w;}}void dijkstra(int n, int s, edgeType dist[maxn]){bool visited[maxn];for(int i=0; i<n; ++i){visited[i] = false;dist[i] = inf;}dist[s] = 0;while(1){edgeType minDist = inf;int minIndex;for(int i=0; i<n; ++i){if(visited[i]){continue;}if(minDist == inf || dist[i] < minDist){minDist = dist[i];minIndex = i;}}if(minDist == inf){break;}visited[minIndex] = true;for(int i=0; i<n; ++i){if(visited[i]){continue;}int dis = graph[minIndex][i];if(dis == inf){continue;}if(dist[i] == inf || dist[minIndex] + dis < dist[i]){dist[i] = dist[minIndex] + dis;}}}}
public:int findTheCity(int n, vector<vector<int>>& edges, int distanceThreshold) {initEdge(n);for(int i=0; i<edges.size(); ++i){int u = edges[i][0];int v = edges[i][1];edgeType w = edges[i][2];addEdge(u, v, w);addEdge(v, u, w);}int retCnt = 100000000;int retIdx = -1;for(int i = n-1; i >= 0; --i){edgeType dist[maxn];dijkstra(n, i, dist);int cnt = 0;for(int j=0; j<n; ++j){if(dist[j] <= distanceThreshold){++cnt;}}if(cnt < retCnt){retCnt = cnt;retIdx = i;}}return retIdx;}
};

代码练习三,对应力扣,前往目标的最小代价,代码见下

long long point[402];
int pointSize;#define base 100001
int findPoint(int x, int y){long long p = (long long)x * base + y;for(int i=0; i<pointSize; ++i){if(p == point[i]){return i;}}point[pointSize++] = p;return pointSize - 1;
}
#define maxn 402
#define edgeType int
#define inf INT_MAXclass Solution {
edgeType graph[maxn][maxn];void initEdge(int n){for(int i = 0; i < n; ++i){for(int j = 0; j < n; ++j){graph[i][j] = inf;}}}void addEdge(int u, int v, edgeType w){if(graph[u][v] == inf || w < graph[u][v]){graph[u][v] = w;}}void dijkstra(int n, int s, edgeType dist[maxn]){bool visited[maxn];for(int i=0; i<n; ++i){visited[i] = false;dist[i] = inf;}dist[s] = 0;while(1){edgeType minDist = inf;int minIndex;for(int i=0; i<n; ++i){if(visited[i]){continue;}if(minDist == inf || dist[i] < minDist){minDist = dist[i];minIndex = i;}}if(minDist == inf){break;}visited[minIndex] = true;for(int i=0; i<n; ++i){if(visited[i]){continue;}int dis = graph[minIndex][i];if(dis == inf){continue;}if(dist[i] == inf || dist[minIndex] + dis < dist[i]){dist[i] = dist[minIndex] + dis;}}}}public:int minimumCost(vector<int>& start, vector<int>& target, vector<vector<int>>& specialRoads) {pointSize = 0;initEdge(maxn);int s = findPoint(start[0], start[1]);int t = findPoint(target[0], target[1]);for(int i=0; i<specialRoads.size(); ++i){int u = findPoint(specialRoads[i][0], specialRoads[i][1]);int v = findPoint(specialRoads[i][2], specialRoads[i][3]);edgeType w = specialRoads[i][4];addEdge(u, v, w);}for(int i = 0; i<pointSize; ++i){int x1 = point[i] / base;int y1 = point[i] % base;for(int j = 0; j<pointSize; ++j){int x2 = point[j] / base;int y2 = point[j] % base;int w = abs(x1 - x2) + abs(y1 - y2);addEdge(i,j, w);}}edgeType dist[maxn];dijkstra(pointSize, s, dist);return dist[t];}
};

http://www.dtcms.com/a/335208.html

相关文章:

  • [Python]PTA:for 求奇数分之一序列前N项和
  • 安卓开发选择题
  • CUDA 编程笔记:CUDA延迟隐藏
  • 通配符 重定向 管道符
  • Java 中重载与重写的全面解析(更新版)
  • 在浏览器端使用 xml2js 遇到的报错及解决方法
  • BM25算法和传统的TF-IDF算法的区别
  • 改进版的QGIS 的(属性查询) identify featrues 功能
  • 算法题Day2
  • 计组-间接寻址
  • 抽象代数 · 代数结构 | 群、环、域、向量空间
  • 【QT】常⽤控件详解(八) Qt窗⼝ 菜单栏 工具栏 状态栏 浮动窗口 五种内置对话框
  • Oracle数据库文件管理与空间问题解决指南
  • Java中 23 种设计模式介绍,附带示例
  • IO流-打印流
  • leetcode hot100数组:缺失的第一个正数
  • 洛谷B3924 [GESP202312 二级] 小杨的H字矩阵
  • 洛谷B3865 [GESP202309 二级] 小杨的 X 字矩阵(举一反三)
  • CSDN部分内容改为视频转到B站-清单
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘opencv-python’问题
  • Cloudflare Tunnel 使用SAAS回源加速配置教程
  • 配置 Docker 镜像加速,解决 docker pull 拉取镜像失败、docker search 查询镜像失败等问题
  • Agent中的memory
  • 异构数据库兼容力测评:KingbaseES 与 MySQL 的语法・功能・性能全场景验证解析
  • MySQL性能优化:10个关键参数调整指南
  • ISO27001 高阶架构 之 支持 -2
  • 概率论基础教程第3章条件概率与独立性(三)
  • 从频繁告警到平稳发布:服务冷启动 CPU 风暴优化实践00
  • implement libwhich for Windows
  • 全面解析Tomcat生命周期原理及其关键实现细节