C++:图的最短路径问题

一、简介

        在非网图中,最短路径是指两顶点之间经历的边数最少的路径。在网图中,最短路径是指两顶点之间经历的边上权值之和最少的路径。

         路径上的第一个顶点称为源点,最后一个顶点称为终点

        最短路径问题是图的一个比较典型的应用问题。例如,给定某公路网的n个城市以及这些城市之间相通公路的距离,能否找到城市A到城市B之间一条距离最近的通路呢?如果将城市用顶点表示城市间的公路用边表示,公路的长度作为边的权值,这个问题就归结为在网图中求顶点A和顶点B的最短路径。

        最短路径问题常见的两种算法是Dijkstra算法Floyd算法

         

二、Dijkstra算法 

         Dijkstra算法是一种用于求解单源最短路径的经典算法。它可以在带权重的、有向或无向的图中找出从起始点所有其他节点的最短路径。该算法要求边的权重为非负数,因此不能处理带有负权重的图。

        其基本思想是通过贪心策略,每次选择未处理节点中距离起始点最近的节点,逐步找到最短路径。

        图采用邻接矩阵存储。

        Dijkstra算法主要包括以下步骤:

  1. 初始化

    • 创建一个数组 dist,用来记录从起点到各个节点的最短距离。初始时,起点到自身的距离为0,其它节点的距离设为正无穷大。
    • 创建一个bool数组 visited,用来记录节点是否已经被处理过。初始时,所有节点都未被处理过。
  2. 循环查找

    • 每次从未被处理过的节点中选出距离起点最近的节点 u,并标记为已处理。
    • 遍历所有与 u 相邻的节点 v,如果通过 u 到达 v 的路径更短,则更新 dist[v],并将 u 作为 v 的前驱节点。
  3. 重复

    • 重复以上步骤,直到所有节点都被处理或找到的最短路径已经不能再更新。
  4. 终止

    • 所有节点被标记为已处理,或者没有可以继续处理的节点时,算法终止。此时,数组 dist 中存放的即是起点到各节点的最短距离。

 

#include <iostream>
using namespace std;
#include <vector>//功能:通过Kijkstra算法求最短路径
//参数:输入起点src、顶点数vertex_num、邻接矩阵edge
vector<int> kijkstra(int src, int vertexNum, vector<vector<int>> edge)
{vector<int> dist(vertexNum, INT_MAX);//存放起点到各顶点的最近距离,初始为最大值INT_MAXvector<bool> visited(vertexNum, false);//存放各顶点的访问状态,初始为未访问falsefor (int i = 0; i < vertexNum; i++)       //更新起点到各顶点的距离{dist[i] = edge[src][i];}dist[src] = 0;                            //起点到起点的距离为0visited[src] = true;                      //将起点标记为已访问//遍历所有节点,更新起点到各节点的最小距离(更新dist[]数组),最多执行(顶点数-1)次即可,实际上(顶点数-2)应该够了for (int j = 0; j < vertexNum-1; j++){int min(INT_MAX), u(-1);              //存储未访问节点中距离起点最近的点的值和下标for (int k = 0; k < vertexNum; k++)   //遍历所有节点{if (!visited[k] && dist[k] < min) //若该节点未被访问且起点到该点的距离较近{min = dist[k];u = k;                        //u为未访问的点中距离起点最近的点}}if (u == -1)                          //若没有未访问的点或者没有连通的点{return dist;                      //返回结果,包含起点到各点的最短距离}visited[u] = true;                   //将最近的这个顶点标记为已访问for (int n = 0; n < vertexNum; n++)  //更新起点到各顶点的距离,使起点到各顶点的距离最近{if (dist[n] > dist[u] + edge[u][n] && !visited[n]) {                                //若从起点到u再到n的距离比直接从起点到n的距离还小dist[n] = dist[u] + edge[u][n];}}}return dist;                             //返回结果,包含起点到各点的最短距离
}int main()
{//设置起点为0,顶点数为5int src(0),dest(4), vertex_num(5);//图的邻接矩阵,INT_MAX表示两点之间无边,0表示同一个点之间的距离vector<vector<int>> edge = {{0      , 10     , 3      , INT_MAX, INT_MAX},{INT_MAX, 0      , 1      , 2      , INT_MAX},{INT_MAX, 4      , 0      , 8      , 2      },{INT_MAX, INT_MAX, INT_MAX, 0      , 7      },{INT_MAX, INT_MAX, INT_MAX, 9      , 0      }};//存放起点到各点的最短距离vector<int> dist;//调用Kijkstra算法求最短路径dist = kijkstra(src, vertex_num, edge);//输入起点到终点的最短距离cout << dist[dest];return 0;
}

 

三、Floyd算法

        Floyd算法是一种用于求解图中任意两个顶点之间最短路径的算法。它适用于带权有向图和无向图,能够处理负权边(但不支持负权回路)。

        Floyd算法的核心思想是利用动态规划的原则,通过对图中每对顶点之间的路径进行更新,逐步找到所有顶点对之间的最短路径。算法使用一个二维数组 dist,其中 dist[i][j] 表示从顶点 i 到顶点 j 的最短路径的权重。  

        同Dijkstra算法,Floyd算法适用于图的邻接矩阵存储结构。

        以下是Floyd算法的具体步骤:

  1. 输入:图的顶点数vertexNum 和边的列表(每条边包含起始顶点、结束顶点及权重)。
  2. 初始化距离矩阵 dist
    • 对于每个顶点 i,设置 dist[i][i] = 0
    • 对于每条边 (u, v, w),设置 dist[u][v] = w
    • 其余的 dist[i][j] 设置为INT_MAX。
  3. 动态规划更新
    • 使用三重循环遍历所有顶点组合 (i, j, k),进行路径更新。
  4. 输出:最短路径矩阵 dist

 

#include <iostream>
using namespace std;
#include <vector>//输入参数:起点src、终点dest、顶点数vertexNum,邻接矩阵edge
void Floyd(int src,int dest,int vertexNum, vector<vector<int>> edge)
{vector<vector<int>> dist(vertexNum, vector<int>(vertexNum, INT_MAX));//最短距离矩阵,存储两点之间的最短距离for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){if (i == j){dist[i][j] = 0;          //自己到自己的距离为0}else if (edge[i][j] != 0){dist[i][j] = edge[i][j]; //设置边的权重}}}//Floyd算法for (int k = 0; k < vertexNum; k++){for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){if (dist[i][k] != INT_MAX && dist[k][j] != INT_MAX)//判断i到k,k到j是否通{dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);//看是i直接到j更近,还是i先经过k再到j更近}}}}//输出结果cout << dist[src][dest] << endl;
}int main()
{// 顶点数量int vertex_num = 4; // 图的邻接矩阵vector<vector<int>> edge = {{0, 5, 0, 10},{0, 0, 3, 0 },{0, 0, 0, 1 },{0, 0, 0, 0 }};//调用Floyd算法求最短路径Floyd(0, 3, vertex_num, edge);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/55732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT 通过鼠标事件实现图片的拖动和缩放

通过鼠标拖动来移动图片&#xff0c;并使用鼠标滚轮来缩放图片。 1、实现步骤&#xff1a; 1、移动图片&#xff1a; 使用QPoint记录图片的偏移量&#xff0c;当鼠标拖动时更新这个偏移量&#xff0c;在paintEvent()中根据偏移量绘制图片。2、缩放图片&#xff1a; 使用滚轮…

人工智能平台 PAI-DSW内置通义灵码实操

人工智能平台 PAI&#xff08;Platform for AI&#xff0c;原机器学习平台PAI&#xff09;是 AI Native 的大模型与 AIGC 工程平台&#xff0c;提供包含数据集管理、算力管理、模型工具链、模型开发、模型训练、模型部署、AI资产管理在内的功能模块&#xff0c;内置100种大模型…

02_23 种设计模式之《抽象工厂模式》

文章目录 一、抽象工厂模式抽象工厂模式的结构应用场景 示例代码&#xff08;C&#xff09;注意事项 一、抽象工厂模式 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;隶属于设计模式中的创建型模式&#xff0c;用于产品族的构建。抽象工厂是指当有多个抽象角…

JVS·智能BI数据可视化图表:普通列表与分组列表配置全解析

使用场景 在可视化配置中&#xff0c;很多场景中需要图形和详细信息的融合展示&#xff0c;那么在图表中可以新增普通列表与分组列表的配置。如下图所示&#xff1a; 配置说明 1、新增组件&#xff1a;配置入口如下图所示&#xff0c;新增组件时&#xff0c;选择普通列表与分…

前端vue-配置请求拦截器

1.配置拦截器&#xff0c;记得20行的导出 2.响应拦截器&#xff0c;记得28行的导出 3.拦截器不止可以拦截&#xff0c;还可以添加内容

Custom C++ and CUDA Extensions - PyTorch

0. Abstract 经历了一波 pybind11 和 CUDA 编程 的学习, 接下来看一看 PyTorch 官方给的 C/CUDA 扩展的教程. 发现极其简单, 就是直接用 setuptools 导出 PyTorch C 版代码的 Python 接口就可以了. 所以, 本博客包含以下内容: LibTorch 初步;C Extension 例子; 1. LibTorch …

【分布式微服务云原生】探索Dubbo:接口定义语言的多样性与选择

目录 探索Dubbo&#xff1a;接口定义语言的多样性与选择引言Dubbo的接口定义语言&#xff08;IDL&#xff09;1. Java接口2. XML配置3. 注解4. Protobuf IDL 流程图&#xff1a;Dubbo服务定义流程表格&#xff1a;Dubbo IDL方式比较结论呼吁行动Excel表格&#xff1a;Dubbo IDL…

合并村庄生活废水处理设备工艺流程

诸城市鑫淼环保小编带大家了解一下合并村庄生活废水处理设备工艺流程 设备的构造 该填料采用优质PVC材料制成&#xff0c;是一种新型的折波填料&#xff0c;间距为30mm&#xff0c;比表面积超过400m/m&#xff0c;具有不易堵塞的特点&#xff0c;表面波纹设计便于膜的附着。 该…

CSS3--美若天仙!?

免责声明&#xff1a;本文仅做分享~ 目录 CSS引入方式 选择器 盒子尺寸和背景色 文字控制属性 单行文字 垂直居中 字体族 font复合属性 文本对齐方式 文本修饰线 color 文字颜色 ----- 复合选择器 伪类选择器 超链接伪类 CSS特性 继承性 层叠性 优先级 Emmet …

H、Happy Number(2024牛客国庆集训派对day7)

题目链接&#xff1a; H-Happy Number_2024牛客国庆集训派对day7 (nowcoder.com) 题目描述&#xff1a; 翻译为中文&#xff1a; 数据范围&#xff1a; 输入样例&#xff1a; 680 输出样例&#xff1a; 326623 分析: 本来以为是dfs&#xff0c;但是看到数据范围1e9, 联想到是…

通信工程学习:什么是三网融合

三网融合 三网融合&#xff0c;又称“三网合一”&#xff0c;是指电信网、广播电视网、互联网在高层业务应用上的深度融合。这一概念在近年来随着信息技术的快速发展而逐渐受到重视&#xff0c;并成为推动信息化社会建设的重要力量。以下是对三网融合的详细解释&#xff1a; 一…

go基础面试题汇总第一弹

init函数是什么时候执行的? init的函数的作用是什么&#xff1f; 通常作为程序执行前包的初始化&#xff0c;例如mysql redis 等中间件的初始化 init函数的执行顺序是怎样的&#xff1f; 分不同情况来回答&#xff1a; 在同一个go文件里面如果有多个init方法&#xff0c;它们…

扩展、包含、泛化-系统架构师(七十七)

1&#xff08;&#xff09;是系统分析阶段结束后得到的工作产品&#xff0c;&#xff08;&#xff09;是系统测试阶段完成后的工作产品。 问题1 A系统设计规格说明 B系统方案建议书 C系统规格说明 D单元测试数据 问题2 A验收测试计划 B测试标准 C系统测试计划 D操作手…

git fetch 和 git pull 的区别

git fetch 和 git pull 的区别 git fetch 功能&#xff1a;git fetch 用于从远程仓库获取最新的代码和提交信息&#xff0c;并将其保存到本地仓库的相应远程跟踪分支中&#xff0c;不会自动合并或修改当前的工作目录或当前分支。 合并&#xff1a;此命令不会自动合并获取的更新…

社团活动助手系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;活动分类管理&#xff0c;用户管理&#xff0c;社团活动管理&#xff0c;报名信息管理&#xff0c;签到登记管理&#xff0c;投票项目管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首…

四款语音转文字神器,一键搞定会议记录!

嘿&#xff0c;朋友们&#xff0c;今天咱们来聊聊那些语音转文字的免费软件吧&#xff01;在这个快节奏的时代&#xff0c;谁不想省点时间&#xff0c;少敲几下键盘呢&#xff1f;尤其是那些开会、采访或者闲聊时&#xff0c;语音消息满天飞的日子&#xff0c;一个好用的语音转…

【业务场景】最全的购物车设计与实现

前言 博主最近在做一个购物商城&#xff0c;正好设计到购物车模块&#xff0c;于是乎全面的来聊一聊购物车模块实现的一些核心要点吧&#xff0c;很值得反复品味的设计&#xff0c;当需要实现购物车的时候&#xff0c;本文应该拿来就能用。 目录 1.需要解决的核心问题清单 2…

Mybatis-plus做了什么

Mybatis-plus做了什么 Mybatis回顾以前的方案Mybatis-plus 合集总览&#xff1a;Mybatis框架梳理 聊一下mybatis-plus。你是否有过疑问&#xff0c;Mybatis-plus中BaseMapper方法对应的SQL在哪里&#xff1f;它为啥会被越来越多人接受。在Mybatis已经足够灵活的情况下&…

【分布式微服务云原生】 RPC协议:超越HTTP的远程通信艺术

目录 RPC协议&#xff1a;超越HTTP的远程通信艺术引言RPC协议的实现方式RPC的核心机制流程图&#xff1a;RPC通信流程表格&#xff1a;不同RPC实现方式的比较结论呼吁行动Excel表格&#xff1a;RPC协议实现方式总结 RPC协议&#xff1a;超越HTTP的远程通信艺术 摘要 RPC&#…

pdsh:一个用于并行执行命令的工具

pdsh&#xff08;Parallel Distributed Shell&#xff09;是一个用于并行执行命令的工具&#xff0c;可以在多个远程主机上同时运行相同的命令。它对于需要在多台服务器上执行批量操作的系统管理员和开发人员非常有用。 pdsh 介绍 主要特性 并行执行&#xff1a; pdsh 可以在…