QQ 群一笔画问题
Author:Huan_yp
一笔画问题,即给定一张无向图 $G(V,E)$,每个点的度数均为偶数或者仅有两个点度数为奇数,需要求出一条不重复经过边的路径,遍历所有的边。
由于在算法竞赛中,这个问题是简单的,这里只讨论在 QQ 群一笔画中,快速解决问题的方式。
归纳构造法证明
已知给定图为一笔画图,故一定满足每个点的度数均为偶数或者仅有两个点度数为奇数,并且图联通,若存在两个点度数为奇数,则从其中一个点开始,否则可以从任意点开始。
执行以下过程。
- 在当前节点任意找一条边,如果可以找到,则重复此过程。
- 如果无法找到:
- 图已经被遍历,结束,得到保存的路径。
- 该点度数为 $0$,所以一定回到了起点或者到了终点。记录并删除该路径中所有边,并回溯到上一个存在出度的点,可以证明一定存在这样的点,否则图不连通。该点的度数一定为偶数,对该点进行上述过程,得到一条首尾相接的路径,插入到原路径,得到完整的欧拉(回)路。
- 容易发现,这样的过程将图遍历了一遍,所以最后得到的是完整的欧拉路径。
代码实现比较简单,只需要使用栈在退出时记录当前节点,得到的,从栈顶到栈底,就是一条完整的欧拉路径。
下面是一个例子:
按 $1->2->5$ 走,$5$ 处无路可走,回到 $2$,记录一条路径 $2->5$,从 $2$ 继续走 $2->3->4->2$,回到了,插入原路径变为 $1->2->3->4->2->5$。
正确的操作方式
由于找边的耗时比较长,我们需要尽可能少的找边。
- 如果有 API 可以读取边的情况,那么直接做一遍上述过程即可得到答案。
- 如果不存在对应的 API,我们直接进行上诉操作,可以拿一个程序记录已经走过的点和边并提示路径。
- 如果图不为欧拉回路,则存在死路,判断方式比较简单,当前点是否为起始点,如果死路位于起始点,直接进行路径回溯操作,即步骤二。否则撤销所有操作,从当前节点开始逆向进行已经进行过的操作。
这样单纯的找边的次数恰好为 m 次,即边数。
回溯和走边的操作总和不会超过 2m。
平均执行次数
考虑图为随机生成,期望的行走次数,感觉是 polylog 级别,但是我不会证明。
蒙特卡洛模拟
咕咕咕,没时间写代码。
采用蒙特卡洛模拟算法对该结论进行验证
严谨数学证明
咕咕咕。
也许可以考虑每条边回溯次数期望 $e_{u,v}$。