给定一个具有 v 个节点和 e 条边的 无向连通图,以及其邻接表 adj。我们需要编写一个函数,如果该图包含 欧拉回路(或环),则返回 2;如果包含 欧拉路径,则返回 1;否则,返回 0。
如果一个图包含 欧拉回路,即一条经过每条边恰好一次并从同一顶点开始和结束的环,那么该图被称为欧拉图。
如果一个图包含 欧拉路径,即一条经过每条边恰好一次但从不同顶点开始和结束的路径,那么该图被称为 半欧拉图。
示例:
> 输入:
>
> !Euler1
>
> 输出:1
>
> 输入:
>
> !Euler2
>
> 输出:2
>
> 输入:
>
> !Euler3
>
> 输出: 0
这个问题可以表述为:“是否可以在不抬起笔且不重复任何边的情况下画出这个图?”
乍一看,这似乎与 哈密顿路径 问题类似,后者对于一般图来说是 NP完全 的。然而,确定一个图是否具有欧拉路径或回路要高效得多:它可以在 O(v + e) 时间 内解决。
方法:
> 我们的想法是利用无向图的一些关键 属性,来帮助我们确定它们是否是 欧拉图(即包含欧拉路径或回路)。
>
> 欧拉回路
>
> 当且仅当以下两个条件都为 真 时,图具有欧拉回路:
>
> – 所有度数非零的顶点都属于同一个连通分量。(我们忽略孤立顶点——即度数为 0 的顶点——因为它们不影响回路。)
> – 图中的每个顶点都具有偶数度。
>
> 欧拉路径
>
> 当且仅当以下两个条件都为 真 时,图具有欧拉路径:
>
> – 所有度数非零的顶点必须属于同一个连通分量。(与欧拉回路相同)
> – 恰好有 零个或两个 顶点具有 奇数 度:
> – 如果 零个 顶点具有奇数度 → 存在欧拉 回路(它也是一种路径)。
> – 如果 两个 顶点具有奇数度 → 存在欧拉 路径(但不是回路)。
> – 如果 一个 顶点具有奇数度 → 在无向图中是 不可能的。(因为无向图中所有度数之和总是偶数。)
>
> 注意: 一个没有边的图是 平凡欧拉图。没有边需要遍历,因此根据定义,它同时满足欧拉路径和回路条件。
>
> 原理是什么?
>
> – 在 欧拉路径 中,每当我们进入一个顶点(起点和终点除外),我们也必须离开它。因此,所有 中间顶点 必须具有偶数度。
> – 在 欧拉回路 中,由于我们在同一顶点开始和结束,每个 顶点都必须具有偶数度。这确保了每次进入顶点都能与离开配对。
实现上述思路的步骤:
- 创建一个邻接表来表示 图,并初始化一个用于 DFS 遍历的 visited 数组。
- 从第一个具有 非零度 的顶点开始执行 DFS,以检查图的连通性。
- 在 DFS 之后,确保所有 非零度 的顶点都被访问过,以确认图是连通的。
- 计算具有 奇数度 的顶点数量,以将图分类为欧拉图或非欧拉图。
- 如果所有度数都是偶数,则该图具有 欧拉回路;如果恰好有两个是奇数,则是 路径。
- 如果有两个以上的顶点具有奇数度或图不连通,则它 不是欧拉图。
- 如果是回路则返回 2,如果是路径则返回 1,如果图不满足欧拉条件则返回 0。
C++
INLINECODEdc959e68`INLINECODE511bf384“