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

代码随想录day58图论8

文章目录

  • 拓扑排序
  • dijkstra(朴素版)

拓扑排序

卡恩算法(Kahn’s Algorithm)思路:
入度数组:

首先计算图中每个节点的入度(即指向该节点的边的数量)。如果一个节点的入度为0,表示没有任何其他节点指向它,意味着它可以被排在拓扑排序的最前面。

BFS队列:

使用一个队列(Queue)来存放所有入度为0的节点,因为它们可以开始拓扑排序。我们从这些节点开始,逐步处理。

遍历节点:

从队列中取出一个节点,将其加入拓扑排序的结果列表中。

对于每一个从当前节点指向的邻接节点,将它们的入度减1。

如果邻接节点的入度减为0,则将该节点加入队列,因为它现在可以加入拓扑排序。

检查是否有环:

如果最终的拓扑排序结果包含所有节点,说明图是有向无环图(DAG),并且找到了合法的拓扑排序。

如果有节点的入度始终不为0,说明图中存在环,无法进行拓扑排序。

题目链接
文章讲解

#include <bits/stdc++.h>
using namespace std;int main() {int v, e;  // v为节点数,e为边数cin >> v >> e;  // 输入节点数和边数// 入度数组,记录每个节点的入度(指向该节点的边的数量)vector<int> indgree(v, 0);// 队列,用来存储入度为0的节点queue<int> q;// 存储拓扑排序的结果vector<int> ans;// 邻接表,用来存储每个节点指向的节点unordered_map<int, vector<int>> m;// 输入所有的边,更新入度数组和邻接表while (e--) {int x, y;cin >> x >> y;  // 输入边的两个端点x和yindgree[y]++;  // 节点y的入度加1m[x].push_back(y);  // 将y加入x的邻接表中,表示有边x->y}// 将所有入度为0的节点加入队列for (int i = 0; i < v; i++) {if (indgree[i] == 0) q.push(i);}// 使用BFS处理入度为0的节点while (!q.empty()) {int cur = q.front();  // 获取队列中的节点q.pop();  // 从队列中移除该节点ans.push_back(cur);  // 将当前节点加入拓扑排序结果// 遍历当前节点指向的所有邻接节点auto k = m[cur];  // 获取当前节点的邻接节点for (int j = 0; j < k.size(); j++) {indgree[k[j]]--;  // 当前邻接节点的入度减1if (indgree[k[j]] == 0) q.push(k[j]);  // 如果该邻接节点入度为0,加入队列}}// 判断是否所有节点都被处理过if (ans.size() == v) {// 如果拓扑排序成功,输出排序结果for (int i = 0; i < ans.size(); i++) {if (i != 0) cout << " " << ans[i];  // 不是第一个节点时,输出空格分隔else cout << ans[i];  // 第一个节点直接输出}} else {// 如果拓扑排序失败,说明图中有环,输出-1cout << -1;}}

dijkstra(朴素版)

以下为dijkstra 三部曲

1、选源点到哪个节点近且该节点未被访问过

源点距离源点最近,距离为0,且未被访问。

2、该最近节点被标记访问过

标记源点访问过

3、更新非访问节点到源点的距离(即更新minDist数组)
题目链接
文章讲解

#include <bits/stdc++.h>
using namespace std;int main() {int n, m;cin >> n >> m; // 输入节点数n和边数m// 初始化图的邻接矩阵,大小为 (n+1) x (n+1),初始值设为 INT_MAXvector<vector<int>> grid(n + 1, vector<int>(n + 1, INT_MAX));// 初始化访问标记数组,所有节点初始为未访问vector<bool> visited(n + 1, false);// 初始化最短路径数组,所有节点的最短路径初始化为 INT_MAXvector<int> mindist(n + 1, INT_MAX);// 读取 m 条边的输入,并更新邻接矩阵 grid[x][y] 为边的权重while (m--) {int x, y, z;cin >> x >> y >> z;grid[x][y] = z;  // x 到 y 的边权重为 z}// 起点 1 到自己的最短距离为 0mindist[1] = 0;int cur = 1;  // 初始时从节点 1 开始// 执行 Dijkstra 算法,遍历每个节点for (int i = 1; i <= n; i++) {int minval = INT_MAX;// 在未访问的节点中,找出最短路径的节点 curfor (int j = 1; j <= n; j++) {if (!visited[j] && minval > mindist[j]) {cur = j;              // 更新当前节点为距离最小的节点minval = mindist[j];  // 更新最小的距离}}// 将当前节点标记为已访问visited[cur] = true;// 更新当前节点 cur 的邻接节点的最短路径for (int j = 1; j <= n; j++) {// 如果节点 j 未访问,并且存在从 cur 到 j 的边,且通过 cur 更新后的路径更短if (!visited[j] && grid[cur][j] != INT_MAX && mindist[cur] + grid[cur][j] < mindist[j]) {mindist[j] = mindist[cur] + grid[cur][j];  // 更新最短路径}}}// 如果目标节点 n 的最短路径仍为 INT_MAX,表示无法到达目标节点if (mindist[n] == INT_MAX)cout << -1;  // 输出 -1,表示从节点 1 无法到达节点 nelsecout << mindist[n];  // 输出从节点 1 到节点 n 的最短路径}
http://www.xdnf.cn/news/1254997.html

相关文章:

  • Mysql数据仓库备份脚本
  • Android视图状态以及重绘
  • 快速开发实践
  • 内网穿透原理和部署教程
  • 【Kubernetes】部署 kube-bench 实现 K8s 最佳实践
  • tcpdump问题记录
  • Linux下动态库链接的详细过程
  • 【数据结构初阶】--排序(五)--计数排序,排序算法复杂度对比和稳定性分析
  • Python Socket 脚本深度解析与开发指南
  • MySQL梳理四:事务日志机制和多版本并发控制(MVCC)
  • SpringMvc的原理深度剖析及源码解读
  • 前端页面直接生成PDF下载文件
  • “物联网+职业本科”:VR虚拟仿真实训室的发展前景
  • 物联网架构全解析:华为“1+2+1”与格行随身WiFi,技术如何定义未来生活?
  • 基于开源AI智能名片链动2+1模式S2B2C商城小程序的微商产品经营策略研究
  • 技术优势铸就行业标杆:物联网边缘计算网关凭何引领智能变革?
  • 008 前端vue
  • Spring AOP动态代理核心原理深度解析 - 图解+实战揭秘Java代理设计模式
  • RabbitMQ-日常运维命令
  • 嵌入式硬件中MOSFET基本原理与实现
  • python函数--python010
  • Redis中间件(三):Redis存储原理与数据模型
  • 小红书开源多模态视觉语言模型DOTS-VLM1
  • ubuntu 2024 安装拼音输入法
  • VC6800智能相机:赋能智能制造,开启AI视觉新纪元
  • 【关于Java 8 的新特性】
  • 语言模型(LM):n-gram模型原理与困惑度(Perplexity)计算详解
  • 38.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--增加日志记录器
  • 嵌入式C语言编程:策略模式、状态模式和状态机的应用
  • 首个!3D空间推理框架3D-R1:融合强化学习、推理链、动态视角,实现7大任务SOTA!