欧拉路径(Euler path)/欧拉回路(Euler circuit)/欧拉图(Euler Graph)小结

前言

  想象一下你碰到了哈密顿回路类的问题(NPC问题),但又要在可观的多项式时间内解出。这时,应该怎么破?
  欧拉回路(P问题)闪亮登场!!!它只需你巧妙地重新建一下模,就可以 O ( n + m ) (n为点数,m为边数)从容解决!

定义

  欧拉路径(欧拉通路):通过图中所有边的简单路。(换句话说,每条边都通过且仅通过一次)也叫”一笔画”问题。
  欧拉回路:闭合的欧拉路径。(即一个环,保证每条边都通过且仅通过一次)
  欧拉图:包含欧拉回路的图。

起源历史

  在一个图中求解一条欧拉回路的问题,起源于欧拉提出的、著名的“七桥问题”。详见百度百科

判定(充要条件)

  下列是判定一个图中是否有欧拉回路/欧拉路径的充要条件。

欧拉回路

  1. 图G是连通的,无孤立点。
  2. 无向图奇点数为0;有向图每个点的入度必须等于出度。

欧拉路径

  1. 图G是连通的,无孤立点。
  2. 无向图奇点数为0或2,并且这两个奇点其中一个为起点另外一个为终点。有向图,可以存在两个点,其入度不等于出度,其中一个入度比出度大1,为路径的起点;另外一个出度比入度大1,为路径的终点。

算法

  如果我们判断出(或题目给定)一个图肯定存在欧拉回路,则可以考虑求解一条欧拉回路。

Fleury算法

  目前比较通用的应该是Fleury算法。该算法流程如下:
1. 任取G中一个点x
2. 选择一条从点x出发的边i(若i可以不为桥则不应将i选为桥),设i连向点y,删除i,然后:
  1)i不为桥,走到点y;
  2)i迫不得已必须为桥,走到点y并删去点x(因为删去i后,点x将成为孤立点)。
3. 步骤2无法执行时停止算法
  当算法停止时,依次经过的点所得到的简单回路为图G的一条欧拉回路。

圈套圈算法

  当然,也有一种看似很暴力的圈套圈算法
  这个算法大概是,从某个点开始走,当走到死胡同时就将当前点压入栈(答案栈)中,直到退到某个点仍然存在出边,然后继续沿着出边走下去。 然后答案即为将节点从栈顶一个一个地弹出(反向输出整个栈)。

分析

  先分析一下圈套圈算法。
  首先,设起点为x,则如果在走到点v的时候,我们误打误撞又走回了点v(即走了一个包含点v的环,或者说从点v走回了点v),那么这第一次的点v肯定为点x。因为如果为其他点,则从点x走到点v,又从点v走回了点v,那么v的度数为3,v为奇点,不符合判断条件。
  那么我们一直回溯,一边回溯一边压栈,回溯到一个点y有出边,我们就继续从点y找环。如果点y找到一个环A,我们又回溯压栈。那么显然 y x 的路径先被压入栈中,然后是环A,最后是 x y 的路径。那么我们可以假想,我们从x走到点y的时候,并没有从它走回点x,而是走了一波环A,最后才走回了点x,这样就恰好搞出了一条欧拉回路。
  也就是说,我们会找出包含起点x的一个大环,大环中的每一个点都可能带出一个小环,小环中的每一个点又可能带出一个更小的环……以此算法求出的解(那条欧拉回路),我们走大环走到一个点,若它可以带出一个小环,我们就相当于去先搞了那个小环;尔后才回归大环。


  根据上述分析,Fleury算法实质上等于圈套圈算法。
这里写图片描述
  设起点为1,上图中的大环为{1,10,8,9,1}。我们在走到10时,10能带出一个小环{10,4,2,3,10},上图变成下图:
这里写图片描述
  显然,此时边 10 8 为桥,因为10能带出一个小环;而囿于有条件:若i可以不为桥则不应将i选为桥,我们会优先去搞10带出来的那个小环。转化为实际步骤即为走边 10 4 10 3
  如果设大环为{x,v1,v2,v3,…,vk,x},我们在走到vi时,显然 x v i 的边都已删除;所以边 v i v i + 1 定然是桥。此时,如果vi能够带出一个小环,那么我们肯定会优先去搞那个小环;尔后重新遍历到vi后(从vi走到vi),再走边 v i v i + 1

例题

【JZOJ4004】【GDKOI2015】青蛙跳环
【JZOJ4644】【NOI2016模拟7.16】人生的经验

猜你喜欢

转载自blog.csdn.net/qq_36551189/article/details/80905345