当前位置: 首页 > 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.dtcms.com/a/319799.html

相关文章:

  • windows操作系统定时关机、重启指令记录
  • 一周学会Matplotlib3 Python 数据可视化-坐标轴 (Axis)
  • 进程间数据的关联与隔离
  • 管家婆软件如何设置默认税率?
  • AI创新中心从“空间集聚”到“生态共生”
  • 代码库详细笔记
  • P1690 贪婪的 Copy
  • [airplay2] airplay2简略介绍
  • 前端全局注册知识【持续更新】
  • 二分查找算法,并分析其时间、空间复杂度
  • IIS7.5下的https无法绑定主机头,显示灰色如何处理?
  • [ java SE ] 多人聊天窗口1.0
  • 强光干扰下裂缝漏检率↓82%!陌讯轻量化模型在道路巡检的落地实践
  • 2深度学习Pytorch-自动微分--梯度计算、梯度上下文控制(累计梯度、梯度清零)
  • Ethereum: 像Uniswap V3贡献者一样开发,克隆、编译与测试v3-core
  • 通过减少回表和增加冗余字段,优化SQL查询效率
  • LSTM 单变量时序预测—pytorch
  • vscode+latex本地英文期刊环境配置
  • VScode使用jupyter notebook,配置内核报错没有torch解决
  • 如何委托第三方检测机构做软件测试?
  • 鸿蒙 - 分享功能
  • 直播预告|鸿蒙生态下的 Flutter 开发实战
  • 非化学冷却塔水处理解决方案:绿色工业时代的革新引擎
  • Elasticsearch 文档分词器
  • 神经网络入门指南:从零理解 PyTorch 的核心思想
  • 2025 五大商旅平台管控力解析:合规要求下的商旅管理新范式
  • Flutter 布局控件使用详解
  • 【java基础|第十六篇】面向对象(六)——抽象和接口
  • Java-JVM探析
  • 参考平面与返回电流