news 2026/6/11 13:40:40

有向图Hierholzer算法的另一种实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
有向图Hierholzer算法的另一种实现

由于在有向图中,Hierholzer 算法不需要删除反向边,因此我们可以使用其它更加方便的数据结构来保存图。例如,我们可以使用邻接表^8保存有向边,得到有向图 Hierholzer 算法的另一种 C++ 代码实现。

// e[i] 是一个类型为 vector<int> 的变量,保存了节点 i 与哪些节点之间有边相连 // ans 是一个类型为 vector<vector<int>> 的变量,用来存储我们找到的回路 // 回路用边的形式表示,一条边用有两个元素的 vector<int> 表示 void dfs(int sn) { while (e[sn].size() > 0) { int fn = e[sn].back(); // 删除有向边 sn -> fn e[sn].pop_back(); // 继续遍历相邻点 dfs(fn); // 将边 sn -> fn 加入结果序列中 ans.push_back({sn, fn}); } }

在上述实现中,我们每次遍历的是从 sn 出发,且未被删除的最后一条有向边 sn -> fn。之所以选择最后一条边,是因为我们可以通过 vector 的 pop_back 方法,在 的时间复杂度内删除这条边。因此上述实现的时间复杂度仍然是 的,且比链式前向星的实现方式更加简洁。

例题

我们仍然使用下面这道基础例题^7完整地展示 Hierholzer 算法在有向图中的使用。

直接使用当前弧优化的 Hierholzer 算法即可。本题的 C++ 代码如下。

#include <bits/stdc++.h> #define MAXN ((int) 1e5) #define MAXM ((int) 2e5) using namespace std; int n, m; vector<int> ans; struct Edge { // 因为不需要删除反向边,我们直接把编号为 idx 的边保存在 e[idx] 里 // 这样就不需要额外记一个 idx 了 int fn, nxt; bool del; } e[MAXM + 10]; int p[MAXN + 10]; int inDeg[MAXN + 10], outDeg[MAXN + 10]; // 加入第 idx 条有向边 x -> y void adde(int x, int y, int idx) { e[idx] = Edge { y, p[x], false }; p[x] = idx; } void dfs(int sn) { // 当前弧优化的 Hierholzer 算法 for (int i = p[sn]; i != 0; i = p[sn]) { if (e[i].del) { // 这条边已经被删除了,修改 p[sn] 指向它的下一条边 p[sn] = e[i].nxt; continue; } // 删除有向边 e[i],不需要删除反向边 e[i].del = true; // 继续遍历相邻点 dfs(e[i].fn); // 将边 e[i] 的编号加入结果序列中 ans.push_back(i); } } int main() { // 读入点数和边数 scanf("%d%d", &n, &m); // 读入所有有向边 for (int i = 1; i <= m; i++) { int x, y; scanf("%d%d", &x, &y); adde(x, y, i); outDeg[x]++; inDeg[y]++; } // 检查是否所有点的入度等于出度 for (int i = 1; i <= n; i++) if (inDeg[i] != outDeg[i]) { printf("NO\n"); return 0; } // 必须从一个非零度节点开始深度优先搜索 for (int i = 1; i <= n; i++) if (inDeg[i] + outDeg[i] > 0) { dfs(i); break; } // ans 保存的是欧拉回路的倒序,必须 reverse 才是正确答案 reverse(ans.begin(), ans.end()); // 这里实际上是对原图弱连通性的检查 // 如果原图的非零度节点不连通,那么 ans 里将不足 m 条边 if (ans.size() != m) printf("NO\n"); else { // 输出欧拉回路 printf("YES\n"); for (int i = 0; i < m; i++) printf("%d%c", ans[i], "\n "[i + 1 < m]); } return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 13:40:05

VScode远程GUI调试实战:告别黑屏,用RemoteX11+Xming打通视觉反馈

1. 为什么需要远程GUI调试&#xff1f; 很多开发者都遇到过这样的场景&#xff1a;你在本地用VScode连接远程服务器或嵌入式设备调试代码&#xff0c;当运行到图形显示相关的代码时&#xff0c;终端突然报错"cannot open display"。比如用OpenCV的imshow函数显示图像…

作者头像 李华
网站建设 2026/6/11 13:40:02

STM32F103激光投影键盘全套开发资料:原理图+BOM+源码+文档

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;这套资料专为快速实现激光投影键盘功能设计&#xff0c;主控芯片是常见的STM32F103系列&#xff0c;所有硬件设计文件齐全——包括可直接查看和修改的PDF原理图、Excel格式的元件清单&#xff08;BOM&#xff0…

作者头像 李华
网站建设 2026/6/11 13:39:58

告别文档混乱:3分钟学会用ExtDiff实现Word文档精准比对

告别文档混乱&#xff1a;3分钟学会用ExtDiff实现Word文档精准比对 【免费下载链接】ExtDiff Compare documents using MS Word from the command line. 项目地址: https://gitcode.com/gh_mirrors/ex/ExtDiff 在文档编辑和版本管理过程中&#xff0c;你是否经常遇到这样…

作者头像 李华
网站建设 2026/6/11 13:39:54

Matomo私有化流量统计PHP源码包(含安装向导、100+插件与GDPR合规配置)

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;一套开箱即用的Matomo网站流量统计系统PHP源码&#xff0c;适配PHP 5和MySQL环境&#xff0c;支持本地服务器一键部署。装好就能看实时访客数、热门页面、搜索来源词、用户地域分布、设备类型等基础数据。内置热…

作者头像 李华
网站建设 2026/6/11 13:38:59

生产级机器学习系统:从Notebook到稳定运行的七支柱

1. 项目概述&#xff1a;当模型走出笔记本&#xff0c;真正开始“呼吸”现实世界你有没有经历过这样的时刻&#xff1f;模型在 Jupyter Notebook 里跑得飞起&#xff0c;AUC 0.92&#xff0c;F1 0.88&#xff0c;交叉验证稳如老狗&#xff1b;团队围在白板前击掌庆祝&#xff0…

作者头像 李华