当前位置: 首页 > 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.lryc.cn/news/613619.html

相关文章:

  • 一个设备或系统能够同时管理和监控两个摄像头的配
  • Ethereum: 像Uniswap V3贡献者一样开发,克隆、编译与测试v3-core
  • 【Unity Plugins】使用Magica Cloth 2 实现头发和服饰的效果模拟
  • 职责链模式应用场景与C++实现
  • 前端开发工具大全
  • 大疆前端笔试题目详解
  • PostgreSQL 强制索引:当重复数据让优化器“失明”时的解决方案
  • 实验室课程|基于SprinBoot+vue的实验室课程管理系统(源码+数据库+文档)
  • vue3 el-select 加载内容后 触发事件
  • Mysql自定义顺序查询
  • Mysql 单行函数 聚合函数
  • 六类注定烂尾的甲方软件外包必看!这类甲方不要理-优雅草卓伊凡
  • sigprocmask 函数深度解析
  • 【指南版】网络与信息安全岗位系列(三):安全运维工程师
  • Redis 分布式Session
  • Redis面试精讲 Day 16:Redis性能监控与分析工具
  • 锡膏种类多,不同的锡膏有什么区别,该如何正确选择?
  • 深入理解 ReentrantLock和AQS底层源码
  • Day09 Tlisa登录认证
  • 计算机英语详细总结
  • 类和对象(中):类的默认成员函数、构造函数、析构函数
  • MinHash算法:为什么选择Min而不是Max
  • DM数据库集群操作顺序规范
  • Linux线程学习
  • 分布式面经
  • Redis面试精讲 Day 14:Redis分片策略与一致性Hash
  • Debain12 api方式部署redis服务
  • 51c大模型~合集165
  • Tiger任务管理系统-10
  • Java 中 Object 类的解析:知识点与注意事项