Dijkstra最短路径算法C++带图详解
一、问题定义
求解单元点的最短路径问题:给定带权有向图G和源点v,求v到G中其他顶点的最短路径
限制条件:图G中不存在负权值的边
二、思想
划重点,迪杰斯特拉最最朴素的思想就是按长度递增的次序产生最短路径。即每次对所有可见点的路径长度进行排序后,选择一条最短的路径,这条路径就是对应顶点到源点的最短路径。
Tips:可见点就是从源点开始按广度优先算法遍历顶点的过程中,搜索到的点。
下面来解释一下为什么源点到所有可见点的路径中长度最短的一条就一定是源点到该点的最短路径,会不会存在通过一些当前不可见的点间接到达该点的路径比它短呢?
我们设图G的顶点集合为V,再设一个集合S表示已求得最短路径的终点的集合(S怎么来的下面再说)。
设下一条最短路径(终点为x),那么它只能是弧(v,x)或者通过S中的顶点到达x即(v,vi,....,x)。我们来证明一下:
假设(v,...,x)路径上有一个顶点不在S中,则说明存在一条终点不在S中而长度比此路径还短的路径。但这是不可能的。因为我们按长度递增的顺序来产生各最短路径,所以长度比此路径还短的所有路径均已产生,他们的终点一定在S中。
三、算法
1.初始化。V为G中所有顶点集合,S={v}。D[x]表示从源点到x的已知路径,初始D[v]为0,其余为无穷大。
2.从源点v开始运行一步广度优先算法即找其相邻点。如下图中从源点0开始,找到的可见点为1,2,3.
3.计算可见点到源点v的路径长度,更新D[x]。然后对路径进行排序,选择最短的一条作为确定找到的最短路径,将其终点加入到S中,如此处找到的点为2,故将2加入S。S={v,2}.
4.从S中选择新加入的点运行广度优先算法找其相邻点,重复step3。直至所有点已加入S或者再搜索不到新的可见点(图中存在不联通的点,此时S<V)终止算法。
总结一下:
迪杰斯特拉算法总共就干了两件事:
【1】不断运行广度优先算法找可见点,计算可见点到源点的距离长度
【2】从当前已知的路径中选择长度最短的将其顶点加入S作为确定找到的最短路径的顶点。
例题:
问题 C: 【一本通图 最短路径算法】最小花费
[题目描述]
在n个人中,某些人的银行账号之间可以互相转账。这些人之间转账的手续费各不相同。给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问A最少需要多少钱使得转账后B收到100元。
输入
第一行输入两个正整数n,m,分别表示总人数和可以互相转账的人的对数。以下m行每行输入三个正整数x,y,z,表示标号为x的人和标号为y的人之间互相转账需要扣除z%的手续费 (z<100)。最后一行输入两个正整数A,B。数据保证A与B之间可以直接或间接地转账。
1<=n<=2000
输出
输出A使得B到账100元最少需要的总费用。精确到小数点后8位。
样例输入
3 3 1 2 1 2 3 2 1 3 3 1 3
样例输出
103.07153164
就是从一个点到边,不断更新。
代码如下:
#include <bits/stdc++.h>
#include <algorithm>
using namespace std;
int n, m, x, y, z, a, b;
double ljjz[2001][2001];
double c[2001];
bool vis[2001];
void dijkstra()
{c[a] = 1;for(int i = 1; i <= n; i++){int k = -1;for (int j = 1; j <= n; j++){if (!vis[j] && c[k] < c[j])k = j;}vis[k] = true;for(int j = 1; j <= n; j++)c[j] = max(c[j], c[k] * ljjz[k][j]);}
}int main()
{cin >> n >> m;for(int i = 1; i <= m; i++){cin >> x >> y >> z;double t = (100.0 - (int)z) / 100;ljjz[x][y] = ljjz[y][x] = max(ljjz[x][y], t);}cin >> a >> b;dijkstra();printf("%.8lf\n", 100.0 / c[b]);//cout << c[b] << endl;return 0;
}
Dijkstra最短路径算法C++带图详解相关推荐
- VMware里建立虚拟机快照(带图详解)
VMware里建立虚拟机快照(带图详解) 创建快照 如下图所示,想要创建快照有两种方法 可以自行修改名称和描述,修改好之后电机"拍摄快照"即可 此时大家可以看一下自己的快照是否建立 ...
- 广度优先搜索算法带图详解
1.前言 广度优先搜索https://so.csdn.net/so/search?q=%E5%B9%BF%E5%BA%A6%E4%BC%98%E5%85%88%E6%90%9C%E7%B4%A2&am ...
- 【算法模板】高精度模板(带图详解)
文章目录 一.高精度加法模板 二.高精度减法模板 三.高精度乘法模板 3.1 高精乘以低精(普遍用到) 高精乘以高精 四.高精度除法 4.1.高精度除以低精度 4.2.高精度除以高精度 一.高精度加法 ...
- Iconfont矢量图图标怎么使用带图详解
我们经常在网上看到的一些好看的小图标,很多其实它不是img.png图片,而是矢量图.那什么是矢量图呢?先简单普及一下: 计算机中显示的图形一般可以分为两大类--矢量图和位图. 矢量图使用直线和曲线来描 ...
- uniapp微信授权+获取手机号+解密手机号(带图详解)
那废话不多说,开始今天的教程,我会在尾部添加全部代码,如果你懒的自己写,可以复制我的代码,但是里面的一些数据你需要更换,我会标注出来 1.获取微信信息(我的写法是自动获取,而不需要点击触发事件获取). ...
- Linux常用基础指令、Linux常用工具(软件包)使用带图详解
目录 目录相关指令: 文件相关指令: 压缩解压缩指令: 匹配查找指令: 权限相关指令: Linux常用工具: 指令使用规则:指令 [该指令的详细操作选项] [操作对象(通常有路径)],后面两可不加. ...
- 一文讲懂页面置换算法,带例题详解
目录 什么是页面置换算法? 缺页中断次数和页面置换次数 啥子是缺页? 啥子是中断? 啥子是缺页中断? 缺页中断次数 最佳置换算法OPT和先进先出置换算法FIFO 最佳置换算法OPT ...
- 函数调用栈帧过程带图详解
这里,我们来研究如下代码的栈帧过程.为了初学者理解汇编指令,所以编译环境是在vc++6.0下 #include<stdio.h> #include<stdlib.h>int s ...
- mysql源码安装(带图详解)
** mysql源码安装 ** mysql源码安装 参考教程: https://www.cnblogs.com/igoodful/p/11365494.html https://blog.csdn.n ...
最新文章
- Subscriber class xxx ,xx already registered to event
- 一则鬼故事:如果全世界程序员都消失了
- 【自动驾驶】5. ROS和DDS的区别总结
- imageio.ffmpeg.download() has been deprecated. Use 'pip install im ageio-ffmpeg' instead.'
- HDU-6599 I Love Palindrome String(回文自动机+字符串hash)
- ios 的frame,bound,center
- 卧薪尝胆三千越甲可吞吴
- Mellanox刘通:开放的理念让Mellanox的优势愈加凸显
- Ubuntu进入pycharm创建的虚拟环境的方法(以及如果你安装了anaconda等其它修改了环境变量的东西该怎么进)
- 关于博主 | 联系博主
- iBatis.Net系列(五)-providers.config-
- java模板导出excel_POI导出excel模板三种方式
- 人人视频android资源比ios多,人人视频
- mysql 同义词_在数据库mysql中存储和检索同义词的最佳方法
- JAVA操作Excel 可配置,动态 生成复杂表头 复杂的中国式报表表头
- OpenVINO之链接库
- ubutnu18.04/20.04 接入HDMI显示器后,在 root用户下不能播放声音之解决方案
- ImageWatch无法显示图像
- sw转cad映射文件_SW转CAD图层映射
- 程序员如何管理好自己的思维?