欧拉路与欧拉回路
欧拉路与欧拉回路的定义
如果一张图中的一个路径包括每个边恰好一次,则该路径称为欧拉路。
如果一个回路是欧拉路,则称为欧拉回路。
欧拉路与欧拉回路的存在条件
- 对于无向联通图
- 欧拉路:只有两个点为奇点的无向图存在欧拉路(起点和终点为两个奇点)。
- 欧拉回路:没有奇点的无向图存在欧拉回路。
- 对于有向联通图
- 欧拉路:一个顶点的出度-入度=1,另一个顶点的入度-出度=1,其他所有点入度等于出度时存在欧拉路(起点为出度-入度=1的点,终点为入度-出度=1的点)。
- 欧拉回路:所有点的入度等于出度时存在欧拉回路。
如何求解欧拉路与欧拉回路
我们从确定的起点出发(欧拉回路可以从任意一个节点出发),然后枚举每一条与当前节点相连的边,不停地向下一个节点走,并把走过的边从图中删去。每次把到达当前节点所经过的边加入统计答案的\(res[\) \(]\)数组中,可以证明,这样一定能找到一组合法的解。
代码
inline void dfs(int x,int lst)//dfs跑欧拉回路(无向图版)
{
register int &i=lnk[x];//注意,此处的i前面要加一个&,这样就可以不停修改lnk[x],起到一定的优化效果
for(;i;i=e[i].nxt)//枚举下一条边
{
if(vis[i+1>>1]) continue;//如果这条边已经访问过了,就跳过
vis[i+1>>1]=1,dfs(e[i].to,i&1?(i+1>>1):-(i+1>>1));//标记这条边已访问,搜索下一个点,记录是由这条边通往下一个点的
}
if(lst) res[++res_]=lst;//如果不是起点,就记录下到达当前节点的边
}
inline void dfs(int x,int lst)//dfs跑欧拉回路(有向图版),大致思想同上
{
register int &i=lnk[x];
for(;i;i=e[i].nxt)
{
if(vis[i]) continue;
vis[i]=1,dfs(e[i].to,i);
}
if(lst) res[++res_]=lst;
}
例题
待到再迷茫时回头望,所有脚印会发出光芒