欧拉路径算法
文章目录
一、前言
今天,要学的是欧拉路径~
二、欧拉路径
2.1 概念
对于一个连通的图G,有:
- 欧拉路径 :Euler Path,一条路径,能够不重复 的遍历完所有的边,一笔画完所有的边,所以有些涉及到欧拉路径的问题叫一笔画问题。
- 欧拉回路 :一条路径,能够不重复地遍历完所有的边,并且回到起点 。可以看出欧拉回路也是欧拉路径。(特殊的一类)
- 半欧拉图:一个图,图中存在欧拉路径但不存在欧拉回路。
- 欧拉图:也称E图,图中存在欧拉回路。可以看出欧拉图也是半欧拉图。
2.2 逻辑梳理
如何判断有没有欧拉路径/欧拉回路?
- 无向图:度
- 存在欧拉路径的充要条件:度数为奇数的点只能有0/2个,剩下的点全是偶数即可。(0个是欧拉回路,2个是欧拉路径)
- 存在欧拉回路的充要条件:所有的点的度都得是0/偶数。
- 有向图:入度和出度
- 存在欧拉路径的充要条件:
- 要么所有的点的出度均等于入度;
- 要么除了两个点之外,其余所有点的出度=入度 剩余的两个点:一个满足出度-入度=1(起点) 一个满足入度-出度=1(终点)
- 存在欧拉回路的充要条件:所有点的出度均等于入度
- 存在欧拉路径的充要条件:
注:无向图可以判断为有向图,有向图更重要
怎么找到欧拉路径/欧拉回路?
- 若没有明确告诉,先判断是不是欧拉图(度)
- 找欧拉路径/回路(希尔霍尔策算法 H i e r h o l z e r Hierholzer Hierholzer)
欧拉回路和欧拉路径的区别:起点终点不一致
欧拉路径,起点和终点固定(起点的入度-出度=1
读完题发现找欧拉回路/路径就可以用希尔霍尔策算法~特别有针对性!!!
2.3 希尔霍尔策算法
2.3.1 基本思想
基于 D F S DFS DFS算法,又名"套圈法"
2.3.2 思路
以找欧拉回路为例:
- 寻找子回路:从任意节点u出发,沿着边遍历图,遍历过程中,删除经过的边(打标记就行,还要减去度数)。如果遇到边都删除的节点,就回来了(回到u)。
- 检查有没有其他回路:有没有点的边还没有被删完的,有的话,往另一个方向找。
- 重复第二步,直至没有找到。
上图:

2.3.3 代码
-
选择一个合理的点作为起始点,遍历所有相邻边。
-
深度优先搜索,访问相邻顶点,将经过的边都不再访问。(打标记)
把第一个步骤和第二个步骤合并到 D F S DFS DFS中
-
如果当前顶点没有相邻边,则将顶点加入数组末尾。
-
最后将数组倒叙输出,就是从起点出发的欧拉回路。
cpp
// 基于无向图
#include<iostream>
#include<stack>
using namespace std;
struct Edge
{
int v,nxt,eid; // eid是边的编号
bool del; // =1表示这条边是否被遍历过了
}e[maxe];
//建图略。。。
// 为了方便我们查找某一条有向边的反向边,当我们向链式前向星中加入第i(i从1到m)条无向边x - y时,我们会将有向边 x->y 存储在e[i * 2],有向边 y->x 存储在e[i * 2 - 1],
// 这样,e[i]和e[i^1]就互为反向边
// 我们可以直观地发现,如果时一个偶数x^1,那么答案是偶数x + 1,如果是一个奇数x^1,那么答案是奇数x-1
// ans1是一个类型为vector<int> 的变量,用来存储我们找到的回路(边表示)
// ans2是一个类型为vector<int> 的变量,用来存储我们找到的回路(点表示)
void dfs(int x)
{
for(int i=head[x];i!=-1;i=e[i].nxt)
{
// 这条边已经被遍历过了,跳过
if(e[i].del) continue;
// 删除有向边e[i]和它的反向边e[i^1]
e[i].del=e[i^1].del=true;// 遍历为走过的样子
// 继续遍历相邻点
dfs(e[i].v);
// 将边e[i]加入结果序列中
ans1.push_back(e[i],eid);
}
ans2.push_back(x);
}
// 倒着输出ans即为答案(数组存的答案)
注:
- 终点一定是"死胡同"
- 如果是欧拉回路,先 d f s dfs dfs或者先记录答案都行,因为是回路,可以走回来
- 如果是欧拉路径,一定存在一个终点(死胡同)所以要先 D F S DFS DFS,后记录答案(入栈),此时可以保证记录答案时,该点的出边全部找完,相当于从终点到起点记录答案,可以保证x到终点的路径已经记录,此时x是未记录路径中的终点,避免出错。
- 正着走,可能会出错,倒着走不会
2.4 习题
2.4.1 洛谷
- P2731 [USACO3.3] 骑马修栅栏 Riding the Fences
- P7771 【模板】欧拉路径
三、小结
图的有关算法到这里就告一段落了~