图论算法合集

图论算法合集

Floyd-Warshall 算法

介绍

Floyd-Warshall算法是一种用于计算加权图中所有节点对之间最短路径的算法。该算法以动态规划为基础,通过逐步更新最短路径的估计值来找到最终的最短路径。它特别适用于稠密图,即边数接近于节点数平方的图。

步骤详解
  1. 初始化距离矩阵

    • 创建一个二维数组d,其中d[i][j]表示从节点i到节点j的距离。如果i和j之间有直接边,则d[i][j]是该边的权重,否则d[i][j]设为无穷大。
    • 对于所有i,d[i][i]设为0,因为任何节点到其自身的距离都是0。
  2. 动态规划更新

    • 对于每一个节点k,更新其他所有节点对(i, j)的最短距离。
    • 更新规则为:如果从i到j经过k的路径比直接从i到j的路径更短,则更新d[i][j] = d[i][k] + d[k][j]。
  3. 输出结果

    • 经过更新后,d[i][j]将包含从节点i到节点j的最短路径的距离。
代码实现
#include <bits/stdc++.h>
using namespace std;const int N = 210, INF = 0x3f3f3f3f; // 定义最大节点数和无穷大
int n, m; // 节点数和边数
int d[N][N]; // 距离矩阵int main() {cin >> n >> m;// 初始化距离矩阵,所有距离设为无穷大memset(d, 0x3f, sizeof d);for (int i = 1; i <= n; i++) d[i][i] = 0; // 自己到自己的距离为0// 读入边while (m--) {int a, b, c;cin >> a >> b >> c;d[a][b] = min(d[a][b], c); // 取最小的边权重}// Floyd-Warshall算法for (int k = 1; k <= n; k++) // 枚举中间节点for (int i = 1; i <= n; i++) // 枚举起点for (int j = 1; j <= n; j++) // 枚举终点d[i][j] = min(d[i][j], d[i][k] + d[k][j]); // 更新最短距离// 输出任意两点间的最短距离for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++)if (d[i][j] > INF / 2) cout << "INF "; // 超过无穷大的一半表示无路径else cout << d[i][j] << ' ';cout << endl;}return 0;
}

示例

假设有一个图有4个节点和6条边:

  • 边1: (1, 2, 2)
  • 边2: (1, 3, 6)
  • 边3: (2, 3, 3)
  • 边4: (2, 4, 1)
  • 边5: (3, 4, 1)
  • 边6: (4, 1, 5)
初始化距离矩阵
   1    2    3    4
1  0    2    6    ∞
2  ∞    0    3    1
3  ∞    ∞    0    1
4  5    ∞    ∞    0
经过第一轮k=1的更新
   1    2    3    4
1  0    2    6    ∞
2  ∞    0    3    1
3  ∞    ∞    0    1
4  5    7    11   0
经过第二轮k=2的更新
   1    2    3    4
1  0    2    5    3
2  ∞    0    3    1
3  ∞    ∞    0    1
4  5    7    10   0
经过第三轮k=3的更新
   1    2    3    4
1  0    2    5    3
2  ∞    0    3    1
3  6    8    0    1
4  5    7    10   0
经过第四轮k=4的更新
   1    2    3    4
1  0    2    5    3
2  6    0    3    1
3  6    8    0    1
4  5    7    10   0

最终结果表示了所有节点对之间的最短路径长度。

Dijkstra算法

介绍

Dijkstra算法是一种用于计算单源最短路径的算法,即从一个指定的起始节点到图中所有其他节点的最短路径。该算法适用于有向图和无向图,但要求边的权重为非负数。Dijkstra算法利用贪心策略,逐步扩展最短路径树。

步骤详解
  1. 初始化

    • 设定起点s,初始化距离数组dis,其中dis[s] = 0,其他所有节点的距离初始化为无穷大。
    • 使用优先队列(最小堆)来存储和选择当前最近的节点。
  2. 主循环

    • 每次从优先队列中取出距离最小的节点u,标记为已访问。
    • 更新u的所有邻接节点v的距离,如果通过u到v的距离小于当前记录的距离,则更新dis[v]并将v加入优先队列。
  3. 终止

    • 当所有节点都被访问或优先队列为空时,算法结束。
代码实现
#include <bits/stdc++.h>
using namespace std;
#define INF 1e9 // 定义无穷大int a[105][3], n, m, x, y, s, t;
double mapp[105][105]; // 邻接矩阵表示图
double dis[105]; // 距离数组
bool vis[105]; // 访问标记数组// 计算两点之间的距离
double f(int x1, int y1, int x2, int y2) {return sqrt(double((y2 - y1) * (y2 - y1)) + double((x2 - x1) * (x2 - x1)));
}void Dijkstra() {priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;fill(dis, dis + n + 1, INF); // 初始化距离数组为无穷大pq.push({0, s}); // 起点入队,距离为0dis[s] = 0;while (!pq.empty()) {int u = pq.top().second; // 取出当前距离最小的节点pq.pop();if (vis[u]) continue; // 如果已访问,跳过vis[u] = true; // 标记为已访问for (int j = 1; j <= n; j++) {if (!vis[j] && dis[u] + mapp[u][j] < dis[j]) { // 如果j未访问且通过u到j的距离更短dis[j] = dis[u] + mapp[u][j]; // 更新距离pq.push({dis[j], j}); // 将j入队}}}
}int main() {memset(mapp, 0x7f, sizeof(mapp)); // 初始化图的邻接矩阵为无穷大scanf("%d", &n); // 输入节点数for (int i = 1; i <= n; i++) {scanf("%d %d", &a[i][0], &a[i][1]); // 输入节点的坐标}scanf("%d", &m); // 输入边数for (int i = 0; i < m; i++) {scanf("%d%d", &x, &y);mapp[x][y] = mapp[y][x] = f(a[x][0], a[x][1], a[y][0], a[y][1]); // 计算边的权重}scanf("%d%d", &s, &t); // 输入起点和终点Dijkstra();printf("%.2lf", dis[t]); // 输出从起点到终点的最短距离return 0;
}

示例

假设有一个图有4个节点和4条边:

  • 节点1坐标:(0, 0)

  • 节点2坐标:(2, 2)

  • 节点3坐标:(5, 5)

  • 节点4坐标:(7, 8)

  • 边1: (1, 2)

  • 边2: (2, 3)

  • 边3: (3, 4)

  • 边4: (4, 1)

每条边的权重由节点间的欧几里得距离计算得出。

初始化邻接矩阵
   1    2    3    4
1  0    2.83 ∞   ∞
2  2.83 0   4.24 ∞
3  ∞   4.24 0   3.61
4  ∞   ∞   3.61 0
Dijkstra算法过程
  1. 起点为1,距离初始化为:dis = [0, 2.83, ∞, ∞],节点1入队。
  2. 节点1出队,标记为已访问。更新节点2的距离。
  3. 节点2出队,标记为已访问。更新节点3的距离。
  4. 节点3出队,标记为已访问。更新节点4的距离。
  5. 最终,dis = [0, 2.83, 7.07, 10.68],节点4的最短距离为10.68。

总结

Floyd-Warshall算法适用于计算所有节点对之间的最短路径,时间复杂度为O(n^3),适用于稠密图。Dijkstra算法用于计算单源最短路径,时间复杂度为O((V+E) log V),适用于边权非负的稀疏图。

通过实际代码示例和详尽的注释,我们理解了两种算法的核心思想和实现细节。在实际应用中,根据问题的性质选择合适的算法可以提高效率和准确性。

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

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

相关文章

DataEase一键部署:轻松搭建数据可视化平台

DataEase是一个开源的数据可视化和分析工具&#xff0c;旨在帮助用户轻松创建和共享数据仪表盘。它支持多种数据源&#xff0c;包括关系型数据库&#xff0c;文件数据源&#xff0c;NoSQL数据库等&#xff0c;提供强大的数据查询、处理和可视化功能。DataEase 不仅是一款数据可…

通信原理-思科实验四:静态路由项配置实验

实验四 静态路由项配置实验 一&#xff1a;实验内容 二&#xff1a;实验目的 三、实验原理 四、实验步骤 选择三个2811型号的路由器 R1、R2、R3 路由器默认只有两个快速以太网接口&#xff0c;为路由器R1和R3增加快速以太网接口模块NM-1FE-TX&#xff0c;安装后检查路由器的接…

【电源专题】结合锂电池相关资料和华为手机聊聊锂离子电池使用条件限制

在文章:【电源专题】锂电池的特点和工作原理 中我们讲到了一些关于锂电池种类和特点、工作原理等。但是对于锂离子电池使用条件限制却没有介绍,本文基于手机产商 锂离子电池使用条件-电池性能和应用介绍 | 华为官网 (huawei.com)提供的介绍文档再次深入学习锂离子电池的一些特…

bug+测试用例

bug的概念&#xff1a; 1.当且仅当规格说明是存在的并且正确&#xff0c;程序与规格说明之间的不匹配才是错误。 2.当需求规格说明书没有提到的功能&#xff0c;判断标准以最终用户为准&#xff1b;当程序没有实现其最终用户合理预期的功能要求时&#xff0c;就是软件错误 bug…

区块链浏览器开发指南分享

01 概括 区块链浏览器是联盟链上的一种数据可视化工具&#xff0c;用户可以通过web页面&#xff0c;直接在浏览器上查看联盟链的节点、区块、交易信息和子链信息、标识使用信息等&#xff0c;用以验证交易等区块链常用操作。 02功能模块 区块链网络概览 区块链网络概览显示…

【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件

目录 ​编辑 前言 系统调用 open 参数flags 参数mode write 追加方式 read close 文件描述符 打开多个文件并观察其文件描述符 C语言文件操作 理解一切皆文件 理解open操作 前言 各类语言的文件操作其实是对系统调用的封装 我们经常说&#xff0c;创建一个文件&a…

【数据结构】顺序表(杨辉三角、简单的洗牌算法)

&#x1f387;&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳&#xff0c;欢迎大佬指点&#xff01; 欢迎志同道合的朋友一起加油喔 &#x1f4aa;&#x1f4aa;&#x1f4aa; 谢谢你这么帅…

MySQL可重复读的隔离机制下是否彻底解决了幻读?

答案&#xff1a;没有彻底解决。 一、什么是幻读&#xff1f; 当同一个查询在不同时间产生不同的结果集时&#xff0c;事务中就会出现幻读问题。 幻读关注的是记录数量的不同。 不可重复读关注的是记录内容的不同。 二、快照读和当前读 InnoDB引擎的默认隔离级别是可重复读&…

音视频入门基础:H.264专题(17)——FFmpeg源码获取H.264裸流文件信息(视频压缩编码格式、色彩格式、视频分辨率、帧率)的总流程

音视频入门基础&#xff1a;H.264专题系列文章&#xff1a; 音视频入门基础&#xff1a;H.264专题&#xff08;1&#xff09;——H.264官方文档下载 音视频入门基础&#xff1a;H.264专题&#xff08;2&#xff09;——使用FFmpeg命令生成H.264裸流文件 音视频入门基础&…

Spark 运行架构

运行架构 Spark 框架的核心是一个计算引擎&#xff0c;整体来说&#xff0c;它采用了标准的 master-slave 结构。上图中的 Driver 表示 master &#xff0c;负责管理整个集群中的作业任务调度&#xff1b;Executor 则是 slave&#xff0c;负责实际执行任务&#xff1b; 核心组…

深入解析:百数平台图表联动功能设置与实战应用

在当今数据驱动的时代&#xff0c;图表的联动功能已成为数据分析的得力助手。通过深度整合各类图表&#xff0c;如柱形图、折线图、饼图、雷达图、条形图、透视图、面积图、双轴图、地图以及漏斗图等&#xff0c;我们实现了图表之间的无缝衔接&#xff0c;使得数据的呈现与探索…

Spring Boot的Web开发

目录 Spring Boot的Web开发 1.静态资源映射规则 第一种静态资源映射规则 2.enjoy模板引擎 3.springMVC 3.1请求处理 RequestMapping DeleteMapping 删除 PutMapping 修改 GetMapping 查询 PostMapping 新增 3.2参数绑定 一.支持数据类型: 3.3常用注解 一.Request…

【Ant Design Pro】快速上手

初始化 初始化脚手架&#xff1a;快速开始 官方默认使用 umi4&#xff0c;这里文档还没有及时更新&#xff08;不能像文档一样选择 umi 的版本&#xff09;&#xff0c;之后我选择 simple。 然后安装依赖。 在 package.json 中&#xff1a; "start": "cross-e…

基于微信小程序+SpringBoot+Vue的青少年科普教学系统平台(带1w+文档)

基于微信小程序SpringBootVue的青少年科普教学系统平台(带1w文档) 基于微信小程序SpringBootVue的青少年科普教学系统平台(带1w文档) 这个工具就是解决上述问题的最好的解决方案。它不仅可以实时完成信息处理&#xff0c;还缩短高校教师成果信息管理流程&#xff0c;使其系统化…

qt初入门9:qt记录日志的方式,日志库了解练习(qInstallMessageHandler,qslog, log4qt)

项目中用到qt&#xff0c;考虑有需要用到去记录日志&#xff0c;结合网络&#xff0c;整理一下&#xff0c;做记录。 简单了解后&#xff0c;qt实现日志模块思考&#xff1a; 1&#xff1a;借助qt自带的qInstallMessageHandler重定向到需要的目的地。 2&#xff1a;自己封装一…

CogVideo 实测,智谱「清影」AI视频生成,全民免费,连 API 都开放了!

不得不说&#xff0c;AI 视频生成界最近非常火热~ 前有快手「可灵」开放内测&#xff0c;一下子带火了老照片修复&#xff0c;全网刷屏&#xff1a; 怕是你还没拿到内测资格&#xff0c;被称为 “国货之光” 的「可灵」就结束了免费无限量模式。每天只有66点的免费额度&#x…

看 Unity 组件的源码 —— ILSpy

ILSpy 是开源的 .NET 程序集浏览器和解编译器。 下载 ILSpy ILSpy Github 地址&#xff1a;icsharpcode/ILSpy: .NET Decompiler with support for PDB generation, ReadyToRun, Metadata (&more) - cross-platform! (github.com) 它有 Release 包可以下载 也提供 IDE 的…

静态路由学习笔记

1. 静态路由应用场景 &#xff08;1&#xff09;静态路由由网络管理员手动配置&#xff0c;配置方便&#xff0c;对系统要求低&#xff0c;适用于拓扑结构简单并且稳定的小型网络。 &#xff08;2&#xff09;缺点是不能自动适应网络拓扑的变化&#xff0c;需要人工干预过多。…

Python爬虫技术 第13节 HTML和CSS选择器

在爬虫技术中&#xff0c;解析和提取网页数据是核心部分。HTML 和 CSS 选择器被广泛用于定位网页中的特定元素。下面将详细介绍这些选择器如何在 Python 中使用&#xff0c;特别是在使用像 Beautiful Soup 或 Scrapy 这样的库时。 HTML 选择器 HTML 选择器基于 HTML 元素的属性…

企业公户验证API如何使用JAVA、Python、PHP语言进行应用

在纷繁复杂的金融与商业领域&#xff0c;确保每笔交易的安全与合规是至关重要的。而企业公户验证API&#xff0c;正是这样一位默默守护的数字卫士&#xff0c;它通过智能化的手段&#xff0c;简化了企业对公账户验证流程&#xff0c;让繁琐的审核变得快捷且可靠。 什么是企业公…