代码改变世界

实用算法实现-第 18 欧拉回路

2011-10-26 23:20  myjava2  阅读(838)  评论(0)    收藏  举报
 

18.1    欧拉回路存在性的判断

欧拉回路问题可以分为无向图中的欧拉回路和欧拉通路,有向图中的欧拉回路和欧拉通路。这几个问题大抵相像。

有向欧拉回路有:

定理:假设有像多重图D有性质:当忽略有向边上的方向时,得到的图是连通的,那么D有有向欧拉回路当且仅当D的每个顶点的入度和出度相等。

类似的,对有向欧拉通路有:

定理:D有有向欧拉通路,当且仅当除两个不同顶点B和C之外,D的其它顶点的入度和出度相等,且B的出度比入度大1,C的入度比出度大1。在这种情况下,有向欧拉通路自B出发,至C终止。

由上面的定理可以知道,如果要判断一个有向图的欧拉回路是否存在,需要先判断连通性,再判断出度入度。对于无向图,判断方法类似。

判断连通性可以通过DFS或者并查集来实现。

18.2    欧拉回路的构建

在构建欧拉回路之前需要判断欧拉回路是否存在。

构建欧拉回路可以使用Fleury算法。Fleury算法要求能不走桥就不走桥:

1. 任取v0∈V(G),令P0=v0。

2. 设Pi=v0e1v1e2…eivi已经行遍,按下面方法来从E(G)-{e1,e2,…,ei}中选取ei+1:

a) ei+1与vi相关联;

b) 除非无别的边可供行遍,否则ei+1不应该为Gi=G-{e1,e2,…,ei}中的桥。

3. 当2.不能再进行时,算法停止。

构建欧拉回路的Fleury算法可以实用DFS来实现。

《离散数学》中还介绍了另一种构建欧拉回路的算法,就是任意遍历图,直到形成回路,在回路中选择还与不在回路中的点连接的任意点作为起点,再次遍历余下的图,直到形成回路,将找到的新回路加入原来的回路中。如此反复,直到所有的点都已经包含在回路中。这种算法相比Fleury算法较难控制回路的生成,例如下面的例子似乎就不适合用这种方法解决。

18.2.1    实例

PKU JudgeOnline, 2337, Catenyms.

18.2.2    问题描述

给出一些字符串,判断是否能形成欧拉回路。如果不能,输出“***”。否则输出字典序最小的回路。

18.2.3    输入

2

6

aloha

arachnid

dog

gopher

rat

tiger

3

oak

maple

elm

18.2.4    输出

aloha.arachnid.dog.gopher.rat.tiger

***

18.2.5    分析

在没有特殊要求的情况下,DFS遍历图的结点顺序是可以任选的。但是这里由于加上了字典序最小的要求,所以DFS遍历时需要按照以下的优先顺序:

1. 如果有不是桥的边,遍历这些边中字典序最小的边。

2. 否则,遍历这些这些桥中字典序最小的边。

18.2.6    程序

18.3    实例

PKU JudgeOnline, 1386, Play on Words.

PKU JudgeOnline, 2337, Catenyms.

PKU JudgeOnline, 2513, Colored Sticks.

本文章欢迎转载,请保留原始博客链接http://blog.csdn.net/fsdev/article