最短路径——迪杰斯特拉(Dijkstra)算法

2023-11-12

 如果你要从一个城市到另一个城市,中途可以有很多种换乘方法,根据不同人的需求,怎么样才能实现价格最少(价格和路程成正比)?怎么样能实现换乘次数最少?

有很多种可能的情况,这时候怎么样找到合适的方案呢?

这就需要研究图的最短路径问题。

不过在网图和非网图中,最短路径的含义不一样。因为非网图的边上没有权值,它的最短路径就是经过边数最少的情况;而对于网图来说,最短路径指的是两顶点间经过的边上的权值之和的最小路径,并且路径上的第一个点被称为源点,最后一个点被称为终点。

Dijkstra 算法:这是一个按路径长度依次递增的次序产生最短路径的算法。它并不是一下子就求出一个点到另一个点的最短路径,而是一步步求出他们之间顶点的最短庐江,过程中都是基于已经求出的最短路径求出的最短路径,最终得到你想要的结果,其时间复杂度为 O(n^{2})。

这么说可能有点难懂,先看例题:

如果已知一个网状图,求从 V0 点到其他点的最短路径。

输入

第一行输入两个数 n,m,分别代表顶点数和边数;

第 m+1 行,每行三个数 x,y,z,代表一条边的信息(两个端点和它的权值)

输出

一行数字,一共 n 个数,每个数字代表 V0 到该点的最短路径

样例输入

9 16
0 1 1
0 2 5
1 2 3
1 3 7
1 4 5
2 4 1
2 5 7
3 4 2
5 4 3
3 6 3
4 6 6
4 7 9
5 7 5
6 7 2
6 8 7
7 8 4

样例输出

0 1 4 7 5 8 10 12 16

解题思路

用邻接二维矩阵 a 存储边的信息;

数组 D 临时存储当前最短路径;

数组 P 存放最短路径走过最后一个的下标(比如最短路径是 1->2->3->4,那么 P[4]=3);

数组 final 记录是否找到最短路径; 

首先将每个端点与 v0 的距离存放在 D 数组中,比较得到一个最小值 min,记录下它的下标 k,将 final[k] 赋值为 1,避免重复,然后通过这个下标找是否存在 a[k][w]+min<D[w],满足条件就更新,接着将 k 存入 P[w].

代码如下:

#include<stdio.h>
int a[1000][1000];//邻接矩阵 
int D[1000];//临时存储当前最短路径 
int P[1000];//存放最短路径走过最后一个的下标(比如最短路径是 1->2->3->4,那么 P[4]=3) 
int final[1000];//初始化是 0,当下标对应的值为 1时,说明已经求得最短路径 
int n,m;
void shortestPath_Dijkstra()
{
	int min,v,w,i,j,k;
	for(i=0;i<n;i++)
	{
		final[i]=0;//初始化为零,此时所有的点都未加入路径 
		D[i]=a[0][i];//将 v0与其他边的权值存入 D数组  
		P[i]=-1;//将 P数组初始化 
	}
	D[0]=0;//将 v0到 v0的最短路径赋为 0 
	final[0]=1;//v0的最短路径找到了,将 final数组的值赋为 1 
	for(v=1;v<n;v++)//从 v1开始循环 
	{
		min=99999999;//将 min赋为一个较大值 
		for(w=1;w<n;w++)
	    {
		    if(final[w]!=1&&min>D[w])//找到临时数组中的最小值且该点没有被找到过 
		    {
			    min=D[w];//更新 
			    k=w;
		    }
    	}
	    final[k]=1;//找过后要将 final赋值为 1,避免重复
	    for(w=1;w<n;w++)
	    {
		    while(final[w]!=1&&D[w]>min+a[k][w])//min+a[k][w]——该点先前求出的(v0至 vk)最短路径(min)加上 vk与 vw连线的和 
		    {
		    	D[w]=min+a[k][w];//更新 
		    	P[w]=k;
	    	}
	    }
	} 
}
int main()
{
	int i,j;
	int x,y,z;
	scanf("%d %d",&n,&m);//输入顶点数和边数 
	for(i=0;i<n;i++)//将邻接二维矩阵中的值初始化为一个较大值 
	{
		for(j=0;j<n;j++)
		a[i][j]=99999999;
	}
	for(i=1;i<=m;i++)
	{
		scanf("%d %d %d",&x,&y,&z);
		a[x][y]=z;//无向图,两个端点可以双向通过,在邻接矩阵要存两次 
		a[y][x]=z;
	}
	shortestPath_Dijkstra();//进入函数 
	for(i=0;i<n;i++)//输出找到的各端点到 v0的最短路径 
	printf("%d ",D[i]);
	return 0;
} 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最短路径——迪杰斯特拉(Dijkstra)算法 的相关文章

  • 【杰发科技AC7802x测评】4,RTC串口输出

    起初我认为AC7802X的实时实钟会很难 我想留着以后再评吧 可是今天看了RTC说明突然开了悟了 原来RTC只是个计数器 我打开例程并没有发现RTC时钟的例程 到是有个秒中断例程 那也不要紧我把它的功能补全吧 typedef struct

随机推荐

  • 【C++基础学习】引起类模板被实例化情形总结

    在我们使用类模板时 只有当代码中使用了类模板的一个实例的名字 而且上下文环境要求必须存在类的定义时 这个类模板才被实例化 并不是每次使用一个类都要求知道该类的定义 1 声明一个类模板的指针和引用 不会引起类模板的实例化 因为没有必要知道该类
  • 虚拟DOM和真实DOM的区别

    DOM DOM意思是文档对象模型 Dcoument Object Model 它是一个结构化文本的抽象 操作DOM 所以 只要我们想要动态修改网页的内容的时候 我们就修改DOM var item document getElementByI
  • 第二章:25+ Python 数据操作教程(第十七节PYTHON 字典理解与示例)持续更新中

    在本教程中 我们将介绍 Python 中字典理解的工作原理 它包含各种示例 可以帮助您学习字典理解的概念以及如何在现实场景中使用它 什么是词典 字典是Python中的一种数据结构 用于存储数据 以便将值与其相关的键连接起来 大致来说 它的工
  • mac终端操作文件或文件夹(持续更新)

    1 复制文件夹 有文件 cp R 要复制的文件 要复制到哪个路径 2 复制文件 cp 要复制的文件 要复制到哪个路径 3 移动文件夹 mvdir 你要移动的文件夹 要移动到哪里
  • C++ 变量类型

    C 变量类型 变量其实只不过是程序可操作的存储区的名称 C 中每个变量都有指定的类型 类型决定了变量存储的大小和布局 该范围内的值都可以存储在内存中 运算符可应用于变量上 变量的名称可以由字母 数字和下划线字符组成 它必须以字母或下划线开头
  • 手搓のTensorRT网络

    用过TensorRT的基本都接触过trtexec 1 可以方便快捷地将你的ONNX模型转换为TensorRT的engine trtexec onnx model onnx 其中原理是啥 这就涉及到了另外一个库onnx tensorrt 2
  • git 获取不到gitLab创建的新分支

    当我们在日常开发功能的时候 肯定会涉及到新建分支的问题 这时候我们本地的IDE就无法去切换新创建好的分支 因为切换的时候根本找不到那个新建的分支 此时可以可以去通过刷新分支达到发现新分支的目的 找到项目的路径并打开Git Bash Here
  • 第一次作业

    include stm32f4xx h include sys h include delay h include led h include key h int main void u8 MENU NVIC PriorityGroupCo
  • Integer中parseInt(),valueOf(),toString()的区别

    1 parseInt String s int radix 以给出的radix解析s 当不给出radix时 与valueOf 的作用一样 只是s不要超出Integer的范围 2 valueOf String s 把s转换成Integer类型
  • c语言5的阶乘流程图_C语言学习 算法

    1 程序 对数据和操作的描述 算法 数据结构 程序 2 算法的特性 有穷性 在合理的范围内 确定性 无歧义 有零个或多个输入 有一个或多个输出 有效性 3 算法的表示 自然语言 日常用的语言 汉语 英语或其他语言 流程图 4 传统流程图即3
  • 记录Spring boot 项目中druid SQL验证报错但是系统功能正常 报后端报 merge sql error 前端数据查询正常

    异常代码 20 17 49 331 http nio 8081 exec 6 ERROR c a d f s StatFilter mergeSql 169 merge sql error dbType oracle druid 1 2 8
  • SpringBoot整合——阿里云对象存储(OSS)

    SpringBoot整合 阿里云对象存储 1 OSS介绍 在开发应用的过程中 我们经常会有用户需要实名认证之后才能访问的需求 用户认证需要上传证件图片 首页轮播也需要上传图片 因此我们要做文件服务 阿里云oss是一个很好的分布式文件服务系统
  • Docker安装RabbitMQ

    本篇博客主要记录在centos7当中安装RabbitMQ 并且安装完成之后使用外部客户端链接 目录 一 查看docker环境是否正常 二 下载rabbitmq的镜像 三 创建rabbitmq容器 四 访问地址 一 查看docker环境是否正
  • xxx.app已损坏,打不开。您应该将它移到废纸篓解决方法

    1 打开终端 2 在终端中依次输入一下代码 sudo spctl master disable xattr cr Applications xxx app
  • 【springboot开发】项目打包、发布和部署

    前言 可以打包成JAR包独立运行 也可以打包成WAR包部署到Tomcat容器中 若涉及到大规模部署 Jenkins成为最佳选择之一 本文主要介绍Maven项目的打包 发布和部署 目录 1 项目打包 1 1 生成JAR包 1 2 生成WAR包
  • Vue基础知识(Web开发技术)(四)—路由

    这章非常重要哈 编程编程编程 随缘上代码 导读 本章重点 了解vue router的实现原理 熟练路由的安装与使用 掌握路由对象的常用属性和动态路由的匹配及路由嵌套的方法 掌握命名路由 命名视图和编程式导航及query params传参方式
  • VSCode无法在终端使用`conda activate`命令来更换python环境解决方法

    VSCode无法在终端使用conda activate命令来更换python环境 现象 在终端输入conda activate命令后出现如下图所示的报错 原因 powershell默认没有打开脚本加载功能 无法加载conda init 解决
  • 无线传感网络

    第一 二章 无线传感网络的定义 无线传感网络是大量的静止节点或移动的传感器以自组织和多跳的方式构成的无线网络 目的是协作地探测 处理和传输网络覆盖区域内感知对象的监测信息 并报告给用户 传感器节点的组成 数据处理 数据采集模块 传感器 A
  • 最好的网页浏览器_谷歌浏览器双击关闭标签的步骤_如何使Chrome能够双击关闭标签页...

    我们在使用浏览器浏览网页的时候 经常会打开多个书签 很多浏览器都支持双击标签页就可以直接关闭 但是有不少用户使用谷歌浏览器chrome却发现无法直接双击关闭标签页 那么如何使Chrome能够双击关闭标签页呢 我们需要借助扩展程序 现在随小编
  • 最短路径——迪杰斯特拉(Dijkstra)算法

    如果你要从一个城市到另一个城市 中途可以有很多种换乘方法 根据不同人的需求 怎么样才能实现价格最少 价格和路程成正比 怎么样能实现换乘次数最少 有很多种可能的情况 这时候怎么样找到合适的方案呢 这就需要研究图的最短路径问题 不过在网图和非网