算法提高课——3.10 欧拉路径和欧拉回路

image-20210807031457384

欧拉路径和欧拉回路


哥尼斯堡七桥问题


以下内容摘自《信息学奥赛一本通·提高篇》.

欧拉回路问题是图论中最古老的问题之一。它诞生于18世纪的欧洲古城哥尼斯堡,普瑞格尔河流经这座城市,人们在两岸以及河中间的小岛之间建了7座桥,如下图所示:

image-20210807031457384
七桥问题图示

市民们喜欢在这里散步,于是产生了这样一个问题:**是否可以找到一种方案,使得人们从自己家里出发,不重复地走遍每一座桥,然后回到家中?**这个问题如果用数学语言来描述,就是在上图中找出一条回路,使得它不重复地经过每一条边。这便是著名的“哥尼斯堡七桥问题”.

image-20210807031457384
抽象后的图示

注意:桥是只能走一次,但是点(即小岛和两岸)是可以随便走的.


欧拉路径与欧拉回路


G = ( V , E ) G=(V,E) G=(V,E) 是一个图.
欧拉路径:图 G G G 中经过每条边一次并且仅一次的路径称作欧拉路径.
欧拉回路:图 G G G 中经过每条边一次并且仅一次的回路称作欧拉回路.

欧拉路径问题 也被称为 一笔画问题.

性质与定理

假设某图满足欧拉路径,则讨论图中点的 度数 (无向图,直接将 点的连边数 作为 度数):

  • 对于起点来说,其作为起始点往外走度数 + 1 +1 +1​​,之后如果每次经过起点,应该立刻再走出去(走回来就停住就变成 欧拉回路 了)度数 + 2 +2 +2​​,所以起点的度数应为奇数

  • 对于终点同理,终点的度数应为奇数

  • 对于中间点来说,经过此点就应该立即再走出去,度数 + 2 +2 +2​,故中间点的度数应为偶数.

特殊地,当起点与终点为同一个点时,此点度数显然为偶数,当然,此时形成的是欧拉回路;
可以说欧拉回路是特殊的欧拉路径.

如上可以得出 度数为奇数的点只有能 0 0 0 2 2 2 个 是 存在欧拉路径的 必要条件 .

对于无向联通图

  1. 存在欧拉路径的充分必要条件:度数为奇数的点只有能 0 0 0 2 2 2​ 个

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

对于有向联通图

类比无向图.
实际上对于中间点,入度与出度相等即可.
对于起点,出度比入度多一;
对于终点,入度比出度多一;
特殊地,当起点与终点为同一点,则其入度与出度也相等.

  1. 存在欧拉路径的充分必要条件:要么所有点的出度均等于入度;要么除了两个点之外,其余所有点的出度等于入度,剩余的两个点,一个满足出度比入度多一,另一个满足入度比出度多一
  2. 存在欧拉回路的充分必要条件:所有点的出度均等于入度.

充分性证明

如上只证明了 存在欧拉路径或欧拉回路 能 推出 如上的结论,但这仅仅代表 结论是 存在欧拉路径或欧拉回路 的必要条件,仍需证明 其 充分性.

现在需要证明,如上的结论本身 能够推出 其构成的图 都是欧拉路径或欧拉回路:

  • 对于有一个公共点的 一个环 和 一条线段 组成的图,显然存在欧拉路径;同样地对于 有一个公共点的 两个环,显然存在欧拉回路.
image-20210807031457384
两种情况图示
  • 更普遍地想,如果 无向联通图 满足 度数为奇数的点只有 2 2 2 个 的话,从 某个度数为奇数的点 开始进行深度优先遍历,那么除了 起点与终点 之外,走到 中间点 时,由于其度数为偶数,到达中间点时就必然会存在 另外一条 没有走过的边 往外走.

但可能存在搜到终点时,并没有将整个图都遍历完的情况.
这时深度优先搜索的 回溯 就可以将 搜到终点时没有遍历到的点都再遍历到;

另一种理解方式就是,在遍历过程中,终点是有可能先被遍历到的,但这不并影响整个图都被遍历到;
那么都遍历过终点了,深度优先遍历什么时候才会停止呢?实际上如果存在上述情况,实际上当所有公共点所共用的环都被遍历完,搜索就会停止,停止在公共点上,然后再往上回溯到起点.

  • 故 欧拉路径 实际上可以看作 一条线段路径 上,有很多 与其有公共点的环 和 与环有公共点的环.

  • 其他结论的证明方式是类似的,有了如上的证明也是显然的了.

有向联通图也不难想,实际上就是把 度数作为区分,对于中间点,有入度就一定有对应的出度.

  • 这样就证明了 充分性.

Q:对于有向联通图来说,从 中间点 出发,一定会有一条回来的边,但 出发的路径 是否一定会走回 出发的 中间点 呢?

A:这是不可能的,因为从 中间点 出发,由于其入度与出度相同,所以只要有一条没有走过的入边,就一定有一条对应的没走过的出边;因为 图联通 且 点的个数有限,所以一定可以在有限步内 走回 出发的中间点.

算法过程

假设现有一张无向连通图,图中只存在两个度数为奇数的点.

  • 从起点出发,没有回溯时的第一条路径,必然会走到终点.

从起点出发的话,一旦出发之后,把所有已经用过的边删掉后,在剩下的图中,对于任何一个不是终点的结点来说(包括起点),度数都是偶数,因此第一条路径走到了某个点上的话,由于此点的度数为偶数,则必然会存在一条能出去的边;
但这个过程不可能是无限的,因为边的数量是有限的,因此最终必然会在终点的位置停止.

  • 这样中间的道路会有很多个环,可以使用以下伪代码的顺序填入序列当中:
dfs(u){
   
	for 从u出发的所有边
		dfs() //扩展
	seq <- u //将 u 加入到序列当中
}

当搜完所有和 u u u 相关的点之后,就可以认为 从 u u u 出发 往后遍历到终点的所有的点 都已经加入了序列当中,此时也就可以将 u u u 也放入序列当中了.
序列储存的是一种欧拉回路的倒序走法,只需要逆序输出就可以了.

欧拉路径从一个度数为奇数的点开始搜;欧拉回路可以从任意点开始搜.

细节

一般的 D F S DFS DFS​ 会用点来判重,时间复杂度为 O ( n + m ) O(n+m) O(n+m).

欧拉回路问题是用边来判重,如果图是一个点但有 m m m 条自己指向自己的自环重边,则对于 欧拉回路来说,走法序列长度为 m m m,而每次都要遍历 m m m 条边是否可走,故时间复杂度可能会达到 O ( m 2 ) O(m^2) O(m2).

这样对欧拉回路时 D F S DFS DFS​​​​ 的优化即为:在经过某一条边时,不是简单地把这条边标记一下,而是把它直接删掉,这样就可以保证每用一条边就会删一条边,每条边就只会被用一次,这样时间复杂度就可以降为 O ( n + m ) O(n+m) O(n+m).

有些题目可能因为使用了随机数据,不加优化可能也可以过;但如果出题人有意卡的话,是很可能卡住的.

如果是有向图的话,每用一条边删掉就可以了;如果是无向图的话,因为每条边建的时候需要建两个方向,所以删边时不能忘记相对应的另一条边,需要同时删掉.

如果边的编号从 0 0 0 开始,那么建边时 ( 0 , 1 ) , ( 2 , 3 ) , ( 4 , 5 ) , ⋯ (0,1),(2,3),(4,5),\cdots (0,1),(2,3),(4,5),都是对应的一组边,可以发现 u    x o r    1 u \;xor\; 1 uxor1(异或)即为编号为 u u u 的边的对应边​.


AcWing 1123. 铲雪车


原题链接

随着白天越来越短夜晚越来越长,我们不得不考虑铲雪问题了。

整个城市所有的道路都是双向车道,道路的两个方向均需要铲雪。因为城市预算的削减,整个城市只有 1 1 1 辆铲雪车。

铲雪车只能把它开过的地方(车道)的雪铲干净,无论哪儿有雪,铲雪车都得从停放的地方出发,游历整个城市的街道。

现在的问题是:最少要花多少时间去铲掉所有道路上的雪呢?

输入格式

输入数据的第 1 1 1 行表示铲雪车的停放坐标 ( x , y ) , x , y (x,y),x,y (x,y)x,y为整数,单位为米。

下面最多有 4000 4000 4000 行,每行给出了一条街道的起点坐标和终点坐标,坐标均为整数,所有街道都是笔直的,且都是双向车道。

铲雪车可以在任意交叉口、或任何街道的末尾任意转向,包括转 U U U 型弯。

铲雪车铲雪时前进速度为 20 20 20 千米/时,不铲雪时前进速度为 50 50 50 千米/时。

保证:铲雪车从起点一定可以到达任何街道。

输出格式

输出铲掉所有街道上的雪并且返回出发点的最短时间,精确到分钟,四舍五入到整数。

输出格式为 hours:minutesminutes 不足两位数时需要补前导零。

具体格式参照样例。

数据范围

− 1 0 6 ≤ x , y ≤ 1 0 6 −10^6≤x,y≤10^6 10

  • 11
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值