欧拉回路

欧拉通路:经过每个点恰好一次的路径

欧拉回路:出发和结束在同一点的欧拉通路

注意以下性质:无向图中,所有点度数之和是偶数;有向图中,所有点入度之和等于出度之和。

欧拉回路一般有两种题型:打印方案判断可行性

看到“每条边都必须经过”这类条件,应第一时间想欧拉回路。

模板

我只会 Hierholzer 算法,不过另一种算法一点用也没有。

stack<ll> st;
void dfs(ll x)
{
	for(ll i=cur[x];i<(ll)a[x].size();i=cur[x])
	{
		cur[x]=i+1;
		dfs(a[x][i]);
	}
	st.push(x);
}
void hierholzer(ll s)
{
	dfs(s);
	while(!st.empty())
	{
		cout<<st.top()<<" ";
		st.pop();
	}
	cout<<"\n";
}

关于为什么要在函数快返回时入栈:对于欧拉回路没问题,但是如果是欧拉通路就有问题了。因为有可能先走到了结束点(死胡同),此时需要先不输出,跑完剩下的部分(一个欧拉回路),再把这一段放在结尾输出,所以需要用栈。

写码细节:

  • 图的特例: 由于这种题一般不会给什么限制,要考虑重边和自环。要考虑图可能不是连通图。
  • 欧拉通路起点: 如果是欧拉通路而不是回路,注意起点终点只能从度为奇数的两个点中选择。
  • 当前弧优化: 见代码吧。
  • 无向图: 要么用邻接矩阵;要么保存每条边对应的编号(正反边用一个编号),然后用vis数组存对应编号是否被通过过即可。
  • P2731 [USACO3.3] 骑马修栅栏 Riding the Fences
  • P7771 【模板】欧拉路径
  • P5921 [POI1999] 原始生物

\(\text{Trick}\) 技巧

类状态机:每个子串出现恰好一次

对于 \(n\)\(k\) 进制数,转化为 \(n-1\)\(k\) 进制数,即可用欧拉回路。见我的题解

入度:判定是否可行

可行性的判定依赖入度。详见 OI-wiki。

入度的某些条件 等价于 连通性问题。可利用这一转化维护很多问题的答案。

  • BZOJ3706 反色刷
  • P3520 [POI2011] SMI-Garbage
  • P36E Two Paths
  • HLP3972 遍历(travel)
  • P209C Trails and Glades
  • P6628 [省选联考 2020 B 卷] 丁香之路
  • P547D Mike and Fish
posted @ 2025-02-20 22:40  Luke_li  阅读(34)  评论(0)    收藏  举报