欧拉路径与欧拉回路

欧拉路径欧拉回路基于哥尼斯堡的七桥问题,首先先将其转化为图论的模型,可以发现四个节点的度数都是奇数,分别为3,3,3,5,我们需要从一个起点出发对于图中的每一条边只能够走一次(一笔画问题),一笔画需要满足:除了起点和终点之外其余点的度数为偶数,起点有一条边需要走出去,而终点有一条边走进来,其余边都是一进一出,而七桥问题中所有节点的度数都为奇数所以不满足条件,所以无法完成一笔画。

欧拉回路与欧拉路径对于无向图和有向图都有相关的性质:

1. 在无向图中,所有边都是连通的

(1)存在欧拉路径的充分必要条件:度数为奇数的点只能够有0个或者2个,起点只有一个则度数为奇数的点为0个,否则只有两个;欧拉回路:特殊的欧拉路径,起点与终点是同一个点;

(2)存在欧拉回路的充分必要条件:度数为奇数的点只能够有0个;

2. 在有向图中,所有边都是连通的

(1)存在欧拉路径的充分必要条件:要么所有点的出度均等于入度,要么存在一个点的出度比入度多1,另一个满足入度比出度多1,其余点的出度均等于入度;

之前只是证明了这些结论的必要条件,如何证明充分条件呢?证明充分性通常有一个常用的技巧:只要能够构造出一种方案将欧拉路径构造出来那么就可以证明结论的充分性。

(2)存在欧拉回路的充分必要条件:所有点的入度均等于出度

我们以构造无向图中存在两个起点的欧拉路径为例子:首先从度数为奇数的起点出发开始做深度优先遍历,在dfs遍历的过程中其实是遍历从起点到终点的路径,并且在遍历的过程中存在很多环,此时我们需要将路径环融合在一起即可,不管是环与环还是环与路径最终都可以融合成一条完整的路径,也即按照深度优先的遍历最终我们一定可以将路径分为若干个环和一条链,环与环之间只存在一个交点,将所有的环与路径融合到一起就可以构造一条欧拉路径,如果度数为奇数的点只有0个,按照dfs遍历的顺序最终必然是很多的环,将所有的环拼接在一起就可以构造一条欧拉回路,而对于有向图的欧拉路径与欧拉回路的构造也是类似的。

欧拉路径与欧拉回路的代码其实都比较简短,在dfs的时候第一条路径一定是从起点到终点的路径,因为从当前点进入就一定会存在一条边出来,所以最终一定会走到终点,中间点的度数一定为偶数,中间点可能存在很多环,如何将环融合进来呢?我们只需要在遍历完节点u的邻节点之后将u加入到欧拉路径的序列中即可, 这样最终得到的就是欧拉路径的逆序。这里需要注意几个细节,因为,一般dfs判重都是以点来判重的,标记点是否已经被访问这样可以保证每一个点只能够被搜一次,欧拉路径是用边来判重的,但是用边来判重的时候可能存在很多个自环,时间复杂度非常高,为O(m ^ 2),我们需要对其优化一下,当我们用过一条边之后那么就将其删除掉,这个时候每条边只会被使用一次,时间复杂度为O(n + m)。

for next in g[u]:
     dfs(...)
# dfs扩展完u的邻接点之后将u加入到序列中

Guess you like

Origin blog.csdn.net/qq_39445165/article/details/121482369