欧拉回路
欧拉通路:经过每个点恰好一次的路径
欧拉回路:出发和结束在同一点的欧拉通路
注意以下性质:无向图中,所有点度数之和是偶数;有向图中,所有点入度之和等于出度之和。
欧拉回路一般有两种题型:打印方案和判断可行性
看到“每条边都必须经过”这类条件,应第一时间想欧拉回路。
模板
我只会 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\) 进制数,即可用欧拉回路。见我的题解。
-
BZOJ3033 太鼓达人
入度:判定是否可行
可行性的判定依赖入度。详见 OI-wiki。
入度的某些条件 等价于 连通性问题。可利用这一转化维护很多问题的答案。
- BZOJ3706 反色刷
- P3520 [POI2011] SMI-Garbage
- P36E Two Paths
- HLP3972 遍历(travel)
- P209C Trails and Glades
- P6628 [省选联考 2020 B 卷] 丁香之路
- P547D Mike and Fish

浙公网安备 33010602011771号