欧拉图
本页面将简要介绍欧拉图的概念、实现和应用。
定义
- 欧拉回路:通过图中每条边恰好一次的回路
- 欧拉通路:通过图中每条边恰好一次的通路
- 欧拉图:具有欧拉回路的图
- 半欧拉图:具有欧拉通路但不具有欧拉回路的图
性质
欧拉图中所有顶点的度数都是偶数。
若
判别法
- 无向图是欧拉图当且仅当:
- 非零度顶点是连通的
- 顶点的度数都是偶数
- 无向图是半欧拉图当且仅当:
- 非零度顶点是连通的
- 恰有 2 个奇度顶点
- 有向图是欧拉图当且仅当:
- 非零度顶点是强连通的
- 每个顶点的入度和出度相等
- 有向图是半欧拉图当且仅当:
- 非零度顶点是弱连通的
- 至多一个顶点的出度与入度之差为 1
- 至多一个顶点的入度与出度之差为 1
- 其他顶点的入度和出度相等
求欧拉回路或欧拉路
Fleury 算法
也称避桥法,是一个偏暴力的算法。
算法流程为每次选择下一条边的时候优先选择不是桥的边。
一个广泛使用但是错误的实现方式是先 Tarjan 预处理桥边,然后再 DFS 避免走桥。但是由于走图过程中边会被删去,一些非桥边会变为桥边导致错误。最简单的实现方法是每次删除一条边之后暴力跑一遍 Tarjan 找桥,时间复杂度是
Hierholzer 算法
也称逐步插入回路法。
过程
算法流程为从一条回路开始,每次任取一条目前回路中的点,将其替换为一条简单回路,以此寻找到一条欧拉回路。如果从路开始的话,就可以寻找到一条欧拉路。
实现
Hierholzer 算法的暴力实现如下:
性质
这个算法的时间复杂度约为
如果需要输出字典序最小的欧拉路或欧拉回路的话,因为需要将边排序,时间复杂度是
应用
有向欧拉图可用于计算机译码。
设有
构造如下有向欧拉图:
设
规定
顶点
边
这样的
任求
例题
洛谷 P2731 骑马修栅栏
给定一张有 500 个顶点的无向图,求这张图的一条欧拉路或欧拉回路。如果有多组解,输出最小的那一组。
在本题中,欧拉路或欧拉回路不需要经过所有顶点。
边的数量 m 满足
解题思路
用 Fleury 算法解决本题的时候只需要再贪心就好,但是由于复杂度不对,所以要换用 Hierholzer 算法。
保存答案可以使用 std::stack<int>
,因为如果找的不是回路的话必须将那一部分放在最后。
注意,不能使用邻接矩阵存图,否则时间复杂度会退化为 std::vector
存图。示例代码使用 std::vector
。
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
|
习题
本页面最近更新:2023/12/19 13:50:33,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:NachtgeistW, aofall, CCXXXI, CoelacanthusHex, countercurrent-time, dkz051, Early0v0, Enter-tainer, Great-designer, H-J-Granger, Haohu Shen, Henry-ZHR, iamtwz, Ir1d, kenlig, leoleoasd, lychees, Marcythm, mcendu, Menci, mgt, orzAtalod, Persdre, PsephurusGladius, shuzhouliu, StudyingFather, SukkaW, Tiphereth-A, YZircon, zhu-yifang
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用