想象你管理着一座巨大的游乐园,园区里散布着大大小小的路口与景点,道路纵横交错。今天你要安排两件表面相似的差事:第一件,让洒水车司机把每一条道路都洒一遍水,每条路恰好洒一次;第二件,让游客把每一个景点都打卡一遍,每个景点恰好逛一次。前者叫“扫街”,后者叫“打卡”——听起来都是“走一圈”的事,可两件差事的难度却天差地别。 扫街的老欧(欧拉 Euler)上手极快,他只要在每个路口数一数有几条路进出,就能立刻判断路线是否可行。而打卡的小哈(哈密顿 Hamiltonian)却愁眉苦脸:没有任何简单公式能帮他判断路线行不行,只能一套方案一套方案地反复试。当景点数量稍多时,可能的方案数量甚至比宇宙中原子的总数还多。 这背后正是图论中两座著名的“大山”——欧拉路径与哈密顿路径。这篇文章就从洒水车与打卡者的故事出发,把它们的定义、判定、算法和复杂度差异一次讲个明白。
学懂欧拉与哈密顿的区别,你就能在算法设计时快速识别“这是边任务还是顶点任务”,避免在 NP 完全问题上空耗算力,这是图论应用与算法面试中的必备直觉。
目录
可视化演示
展示欧拉路径遍历每条边一次、哈密顿路径遍历每个顶点一次,以及P与NP完全问题的复杂度本质差异。
本节配有交互动效(进入视口后自动加载,约 3KB)。
欧拉路径遍历 每条边恰好经过一次 判定条件:0或2个奇度顶点 复杂度:O(E) — Hierholzer算法 欧拉路径存在多项式时间解法,可高效求解
定义起源:七桥与环游世界
1736 年的普鲁士,柯尼斯堡城有一条普雷格尔河穿城而过,河中有两座小岛,两岸与岛之间一共架了七座桥。城里人闲来无事,最爱玩一个“洒水车难题”:能否从某一块陆地出发,不重复地走遍这七座桥,最后还能回到原点?这像极了游乐园里老欧的扫街任务——只不过他面对的是七座桥和四块陆地,目标是“每条路恰好走一次”。
欧拉把这四块陆地压缩成四个点,把七座桥画成连接点的线段,问题立刻变成了一张“图”。他给出了干脆的回答:这种走法根本不存在。这篇论文被公认为图论的起点。一百多年后,数学家哈密顿发明了一个环游世界的游戏:把正十二面体的二十个顶点看作二十座城市,要找一条路线,经过每座城市恰好一次再返回。这正是小哈的“打卡任务”——目标是“每个景点恰好去一次”。
两个问题都叫“路径”,定义却对称地拧着劲。欧拉路径要求遍历每条边恰好一次,哈密顿路径要求遍历每个顶点恰好一次;若要求终点回到起点,则分别是欧拉回路与哈密顿回路。这一字之差,预示了完全不同的命运。
老欧的眼里只有路,小哈的眼里只有景点。同一张地图摆在那里,任务对象不同,接下来的命运就开始分道扬镳了——而第一道分水岭,出现在“能否快速判定”这个问题上。
- 路径的边集 E(P)P 是走过的路线,E(P) 收集这条路线上踩过的所有边。欧拉回路要求这些边恰好装满整张图的边集,每条路都跑且只跑一次。
- 全图的边集 E(G)E 是边集符号,E(G) 表示图 G 里所有道路的集合,共 m 条边。等式表达的正是“一条不漏、一条不多”。
- 路径的顶点集 V(P)V 是顶点集符号,V(P) 是路线经过的顶点集合。哈密顿回路要求每个景点至少到访一次且整条路线闭合。
- 全图的顶点集 V(G)V(G) 是所有景点的集合,共 n 个顶点。对哈密顿回路而言,这个等式就是“全部打卡、不重不漏”的数学表达。
度数判定:路口的岔口计数法
游乐园的老欧想快速知道扫街任务是否可行。他做了个聪明的统计:在每个路口数一数,到底有几条路从这个路口伸展出去。这个数字,图论里叫“度数”。他发现,如果每个路口的道路条数都是偶数,也就是“有进必有出”,那就能设计一条不重复走完所有路的闭合路线。反之,如果某个路口是“死胡同”,道路成单,就容易卡壳。
这个规律就是欧拉定理的核心:一个连通无向图存在欧拉回路,当且仅当所有顶点的度数都为偶数。为什么必须连通?因为如果地图被大河分成两个互不相连的区域,即使两边各自满足偶数度,洒水车也飞不过河,自然无法一笔画完。所以“连通”是地基,“全偶数度”是楼层,缺一不可。
如果图形条件稍稍放宽,恰好有 0 个或 2 个奇数度顶点,图仍然存在欧拉路径——不需要闭合的路线,两个奇度顶点恰好充当起点和终点。比如“一笔画”游戏里的“日”字,中间两个顶点度数为 3,其他为 2,所以能一笔画出但不闭合。
老欧靠着“路口岔口计数法”几秒钟就完成了判定,图纸一摊,结论立现。但判定可行不等于能走通——真正上路时,他还需要学会一件事:在独木桥前保持慎重。
- 顶点度数 deg(v)顶点 v 接出去的道路条数。十字路口有 4 条路,所以 deg=4;丁字路口有 3 条路,所以 deg=3。
- 偶数度的含义度数对 2 取余为 0。对闭合路线来说,每次进入一个路口,必须能匹配到一条出去的路,所以进出要成双。
- 全称量词 所有顶点要求图中每一个顶点都满足偶数度,不允许任何一个“落单”。洒水车老欧必须把每个路口的岔口数都检查一遍。
- 双向箭头 当且仅当条件是充分且必要的。只要连通且全偶数度,欧拉回路必然存在;反过来,只要有欧拉回路,度数必然是偶数。
- 欧拉路径的宽松版若恰好有 2 个奇度顶点,图中仍有欧拉路径,只是不闭合;这两个奇度顶点就是起点和终点。
弗勒里算法:独木桥前的慎重
判定是纸上谈兵,真正握着方向盘的老欧还面临一个陷阱:有些路段是“独木桥”——一旦开过去,整座桥就被封掉,自己可能被困在一小块孤岛上,剩下的路再也洒不着。要避免这种悲剧,老欧给自己立了一条规矩:每次选择下一段路时,只要还有其他选择,就绝对不碰独木桥;只有当面前每一条路都是独木桥时,才被迫走上去。
这条规矩就是 Fleury 算法(弗勒里算法)的核心。把“独木桥”换成图论术语:一条边若是“桥”(删除它会让剩余图不再连通),就尽量别走。完整流程是:首先确认图满足欧拉路径条件;然后从奇度顶点出发(若无奇度顶点,从任意点出发);每一步扫描当前顶点的未走边,优先选择非桥边;走完一条边就把它从图中删掉;重复直到所有边走完,得到一条完整的欧拉回路。
这个算法是典型的贪心策略。它的巧妙之处在于,用“当前图”的连通性来指导每一步选择,而不是全局规划。每一条非桥边的选择都保证:走完之后,剩余边仍然可以通过未来的路线连成一体。
弗勒里算法让老欧走得既稳又全,每一步都确保退路存在,最终完整地扫过所有道路。欧拉问题从判定到构造都有了漂亮的多项式算法——可另一边的小哈,就没有这么好运了。
- 当前图 G已经走过的边从图中移除后,剩下的图叫 G'。决策永远基于此刻还剩下哪些路可走。
- 桥的定义当一条边被删掉之后,剩余图被分成两个互不相连的部分,这条边就是桥。桥是“路线上唯一的咽喉”。
- 非桥优先在候选边里,优先挑不是桥的边走,这样不会把剩余路线截断。
- 万不得已才走桥若当前顶点可选的所有边都是桥,说明前方别无选择,也只能硬着头皮走过去。
NP完全性:打卡路线的指数噩梦
游乐园的小哈想把 20 个景点全部打卡,他随手列出所有可能的顺序:20! 种,也就是 20 × 19 × 18 × …… × 1,约等于 2.43 × 10^18 种。即使每秒能验证一百万种方案,也需要七万多年才能穷举完。小哈崩溃了:有没有什么像“数路口”那样的简单规则,能直接判断打卡路线是否存在呢?
遗憾的是,两百年来数学家们也没找到这样的规则。哈密顿路径的判定问题成了第一批被证明的 NP 完全问题之一。所谓 NP 完全,可以通俗理解为“困难俱乐部”的元老成员:全世界成千上万个难以快速求解的问题,都能在多项式时间内转化为哈密顿问题;只要哈密顿问题找到多项式算法,整个俱乐部的难题都会迎刃而解——这等价于计算机科学中著名的 P=NP 猜想。
对普通开发者而言,不需要会证明,只需要记住后果:求哈密顿路径,目前没有已知的多项式级“捷径”。所有精确算法在最坏情况下都退化为指数时间。比赛中能暴力搜索的规模极限通常只有 n≤20 左右,再大就束手无策。
老欧的洒水车路线五分钟规划完毕,小哈的打卡路线却要用近乎“宇宙寿命”的时间去穷举。这就是“简单”与“困难”肉眼可见的差距。现在,让我们把两位主角放在同一张表格里,看看它们到底差在哪里。
- n 个顶点的排列哈密顿路径要确定 n 个景点的访问先后顺序,本质是给 n 个元素排序。
- 阶乘的展开第一个位置有 n 种选择,第二个位置剩 n-1 种……全部乘起来,就是 n! 种排列顺序。
- 大 O 记法O 描述计算量随 n 增长的量级。n! 增长极快,远超任何多项式函数如 n² 或 n³。
- 和欧拉的对比欧拉判定只需扫一遍顶点和边,复杂度是 O(V+E);哈密顿判定却是 NP 完全,这一刻的对比无比刺眼。
核心区别:边任务与顶点任务的分野
把洒水车老欧和打卡者小哈并排站好,最本质的区别其实只有三个词:作用对象、判定难度、求解复杂度。欧拉回路处理的是“边”,谁在乎一个顶点被走过几次呢?路线可以反复经过同一个路口,只要每条路只走一次即可。哈密顿回路处理的是“顶点”,每个景点只能去一次,道路反而可以用不完。
正因为作用对象不同,两者的数学难度发生了断裂。欧拉问题拥有度数定理这样的完美充要条件,判定是线性的,构造有弗勒里算法;哈密顿问题则是 NP 完全,没有简单的充要条件,没有多项式级的构造算法,精确求解只能靠指数级搜索。完全图 K_n 里任意一个顶点排列都是哈密顿路径,共有 n! 条——这个公式恰恰暴露了它是“排列问题”,而排列问题极少有捷径。
对比起来,欧拉问题像“系统性扫街”:路是任务,点可以重复;哈密顿问题像“行商打卡”:点是任务,路只是连接工具。前者是图论里少数能被彻底征服的问题,后者则是计算机科学里公认的硬骨头。
记住这句话:在算法设计里,能数路口就绝不要排列景点。懂得先判断“这是边任务还是顶点任务”,你就已经赢了一半。而另一半,藏在真实世界的那些看似无关的问题中。
- 欧拉的复杂度判定只需统计度数再检查连通,消耗 O(V+E);弗勒里构造最坏 O(E²)。整体上是温和的多项式时间。
- 哈密顿的复杂度判定本身就是 NP 完全,最坏情况下所有已知精确算法都是指数级。
- 完全图上的排列数K_n 中任意顶点排列都相邻连通,所以哈密顿路径数量就是全排列数量,这是“点任务”的典型特征。
- 规模现实的差距n=50 时,欧拉度数检查只需扫描几百条边,而 50! 超过 3×10^64,比宇宙原子数还恐怖。
实际应用:从扫地机器人到 DNA 测序
游乐园老板终于明白了这个道理,开始把两类任务应用到运营中。洒水车要覆盖全部道路且尽量不重复,这是标准欧拉问题;而贵宾体验师想用最短路线玩遍所有景点,这是哈密顿问题,本质是旅行商问题(TSP)——对所有景点排列求总距离最小值。前者用弗勒里算法或更快的 Hierholzer 算法轻松解决,后者只能借助近似算法。
走出游乐园,欧拉与哈密顿的用武之地更广。扫地机器人把房间划成网格,把“需要清扫的相邻格子边界”当边,规划欧拉回路实现全覆盖且少重复;搜索引擎爬虫遍历网页链接时,也常遇到类似“走遍所有链接”的欧拉型路由问题。而哈密顿路径则在基因组测序中唱主角:经典的重叠图拼接策略,正是要在“每个测序片段是一个顶点”的图上,找出一条经过所有顶点的哈密顿路径来还原完整基因组。
在算法竞赛中,这两类问题也是常客。例如“单词接龙”类题目要求用每个单词的首尾字母拼接成链,把字母当顶点、单词当边,就化归为欧拉路径判定;而“小规模旅行推销员”则要求用状态压缩动态规划硬啃哈密顿回路。判断题型决定工具:见到边任务,立刻想到度数定理和欧拉算法;见到点任务,立刻想到 NP 完全并调整策略。
从游乐园到实验室,从扫地机器人到基因组,欧拉负责“把每条路都走遍”的完美方案,哈密顿负责“把每个点都逛完”的艰难抉择。理解了它们的区别,你就掌握了图论中最重要的一道分界线。
- 访问顺序排列 pp_1 到 p_n 是 n 个景点的访问顺序,每种排列对应一条哈密顿路径。
- 相邻距离 dd(p_i,p_{i+1}) 表示从第 i 个景点到第 i+1 个景点的距离,可以是直线距离或实际路况距离。
- 总路程求和把沿途所有相邻距离加在一起,得到这条打卡路线的总长度 L。
- 全局取最小在所有可能的哈密顿回路中挑选总长度最小的那一条,这正是旅行商问题的核心。
AI 应用场景
扫地机器人的全覆盖路径规划
阶段:路径规划与决策
解决的问题:传统随机碰撞式扫地机器人效率低、容易漏扫;若把房间划分成网格,把需要清扫的相邻区域边界当作“边”,扫地机器人要扫过每条边恰好一次,这正是欧拉回路问题。用度数判定确认方案可行,再套用弗勒里算法规划路线,能实现“全覆盖、少重复”的清扫路径。
具体案例:某家用机器人团队在 10m×10m 的客厅地图上建立网格图,用欧拉回路算法生成扫街式路径,相比随机碰撞模式,清扫覆盖率从 82% 提升到 99%,重复率下降 40%。
DNA 测序中的序列组装
阶段:生物信息数据处理
解决的问题:基因测序仪把长链 DNA 打碎成海量短片段,拼接时把每个片段看作顶点、片段间的重叠关系看作边,寻找一条经过所有片段的哈密顿路径来还原完整序列;而新一代 de Bruijn 图策略则把 k-mer 当顶点,同样的问题转化为找欧拉路径。两种路径模型在同一个生物问题里“同台竞技”。
具体案例:在细菌基因组组装中,OLC 策略(哈密顿型)处理较长片段效果好,de Bruijn 图策略(欧拉型)对重复序列更稳健,工程师需要根据测序平台选择合适的图模型,才能拼出完整基因组。
物流配送的路线优化
阶段:调度优化
解决的问题:快递员每天要访问辖区内全部客户点并返回仓库,目标是总路程最短——这是标准的哈密顿回路最小化(TSP)。由于哈密顿问题是 NP 完全,无法用暴力穷举,实际系统使用 LKH、蚁群或遗传算法等近似方法求次优解。
具体案例:某同城配送平台为骑手规划订单配送顺序,用 TSP 近似算法把 20 个客户点的配送路线长度缩短 18%,高峰期日均单量提升 12%。
Python 演示
# -*- coding: utf-8 -*-"""欧拉路径判定 + Fleury 算法 + 哈密顿暴力搜索演示""" from collections import defaultdict def euler_type(edges, n): """返回: 0=无欧拉路径, 1=有欧拉路径, 2=有欧拉回路""" g = defaultdict(list) for u, v in edges: g[u].append(v) g[v].append(u) odd = sum(1 for v in range(n) if len(g[v]) % 2) if odd not in (0, 2): return 0 seen = set() def dfs(v): seen.add(v) for w in g[v]: if w not in seen: dfs(w) start = next((v for v in range(n) if len(g[v])), 0) dfs(start) if any(len(g[v]) and v not in seen for v in range(n)): return 0 return 1 if odd == 2 else 2 def fleury(edges, n): """Fleury 算法求解欧拉回路, 返回边序列""" adj = defaultdict(list) for i, (u, v) in enumerate(edges): adj[u].append((v, i)) adj[v].append((u, i)) used = [False] * len(edges) def is_bridge(u, v, ei): used[ei] = True seen = {u} stack = [u] while stack: x = stack.pop() for y, j in adj[x]: if not used[j] and y not in seen: seen.add(y) stack.append(y) used[ei] = False return v not in seen start = 0 for v in range(n): if len(adj[v]) % 2 == 1: start = v break path = [] def tour(v): while True: cands = [(w, ei) for w, ei in adj[v] if not used[ei]] if not cands: break w, ei = cands[0] for w2, ei2 in cands: if not is_bridge(v, w2, ei2): w, ei = w2, ei2 break used[ei] = True path.append((v, w)) v = w tour(start) return path def hamilton_bruteforce(edges, n): """暴力搜索一条哈密顿路径, 只适合 n <= 9""" adj = [set() for _ in range(n)] for u, v in edges: adj[u].add(v) adj[v].add(u) for start in range(n): stack = [(start, [start], {start})] while stack: v, path, seen = stack.pop() if len(path) == n: return path for w in adj[v]: if w not in seen: stack.append((w, path + [w], seen | {w})) return None if __name__ == '__main__': # 两个三角形共享顶点0, 全偶数度, 有欧拉回路 edges = [(0, 1), (1, 2), (2, 0), (0, 3), (3, 4), (4, 0)] n = 5 t = euler_type(edges, n) print("欧拉判定:", "回路" if t == 2 else "路径" if t == 1 else "不存在") print("Fleury 欧拉回路:", fleury(edges, n)) print("哈密顿路径:", hamilton_bruteforce(edges, n))
odd = sum(1 for v in range(n) if len(g[v]) % 2)统计奇数度顶点个数,这是欧拉判定的一号标准。if odd not in (0, 2): return 0奇度顶点数量不是 0 或 2,直接宣告没有欧拉路径,这是度数定理的核心应用。if any(len(g[v]) and v not in seen for v in range(n)):检查是否所有非孤立顶点处在同一个连通块里,防止“河对岸”的孤岛。def is_bridge(u, v, ei):桥检测函数:临时删掉一条边,用 DFS 看能否绕过它到达对岸。cands = [(w, ei) for w, ei in adj[v] if not used[ei]]收集当前顶点所有尚未走过的候选边,对应老欧在路口探头张望。for w2, ei2 in cands: if not is_bridge(v, w2, ei2):Fleury 贪心核心:优先取不是桥的边,避免自断退路。stack = [(start, [start], {start})]哈密顿暴力搜索的初始状态,从每个顶点开始深度优先穷举全部排列。
常见误区
误区我觉得欧拉是每条边一次,哈密顿是每个顶点一次,这不就是把“边”换成“顶点”嘛,难度应该差不多,会一个就会另一个。
正解定义确实对称,但复杂度天差地别。欧拉问题有度数定理给出线性时间的充要判定,哈密顿问题则是 NP 完全,没有任何已知多项式判定手段。就像“把房间打扫干净”和“把房间里的玩具按顺序排队”,前者有成熟流程,后者组合爆炸。这种难度断裂正是图论最反直觉的地方。
为何常见:初学时的定义表述太对称,容易让人误以为背后是对偶关系,而忽略了计算复杂性这道鸿沟。
误区我记得欧拉回路的条件是所有顶点度数都是偶数,那我随便画一个全偶数度的图,不就一定有欧拉回路吗?为什么我画的图走不出来?
正解你很可能漏掉了连通性前提。图若被分成两个互不连通的子图,每个子图内部虽然全偶数度,但没有道路连接,洒水车不可能飞过去。判定时必须加一句:所有非孤立顶点必须处于同一个连通分量里。分居两岸的“偶数度小岛”合起来并不是一个可一笔画的整体。
为何常见:教材常把“度数条件”放在标题位置,连通性作为条件一笔带过,学习者只记住了前半句,做题时便踩坑。
误区我以为欧拉回路就是欧拉路径,反正都要走完所有边,回不回到起点无所谓。
正解回路要求终点回到起点,且所有顶点度数为偶数;而欧拉路径允许恰好 2 个奇度顶点,这两个顶点就是起点和终点。比如“一笔画”一个“日”字,中间两点度为 3,它有一笔画的路径但不能闭合回起点。类似地,哈密顿回路与哈密顿路径也是同样的闭合性区别。判定时先分清楚题目要的是“路径”还是“回路”,条件完全不同。
为何常见:中文里“路径”和“回路”听起来像一回事,但在图论中“闭合”二字直接改变判定条件和算法选择。
误区Fleury 算法能找欧拉回路,那我把图的顶点当目标,用同样的贪心思路选边走,应该也能找哈密顿路径吧?
正解Fleury 的“非桥优先”策略之所以正确,是因为欧拉问题有度数定理兜底,保证非桥边的选择不会破坏整体可行性。哈密顿问题是 NP 完全,没有任何贪心规则能保证不走到死胡同。硬套 Fleury 型贪心只会得到一条很长的路径,却几乎不可能保证恰好覆盖所有顶点。算法可以借鉴思想,但不能跨界搬运保证性。
为何常见:两类问题都叫“路径”,新手容易把欧拉问题的贪心算法误当成通用路径算法。
误区我知道哈密顿是 NP 完全,但我的搜索加了剪枝,几十个顶点很快也能出结果,是不是实际没那么难?
正解剪枝只能优化常数,无法改变最坏情况的指数增长。在竞赛中 n≤20 时状态压缩可行,n≤30 加剪枝也许能碰运气,但 n=50 时排列数量是 50!≈3×10^64,任何剪枝都救不回来。精确算法之外的正确出路是换赛道:用近似算法、启发式算法或动态规划在特定结构上求次优解,而不是硬拼暴力搜索。
为何常见:刷题时常用的小图让剪枝效果“看起来很好”,让人误以为指数级只是理论恐吓,直到真实数据把运行时间拉满才醒悟。
面试题
Q1. 一个连通无向图存在欧拉回路的充要条件是什么?
- A.每个顶点的度数都是偶数← 正确答案
- B.恰好两个顶点的度数为奇数
- C.至少有一个顶点的度数为零
- D.边数恰好等于顶点数
答案:A。欧拉回路要求“有进有出且能回起点”,所以所有顶点度数必须为偶数,此外还要保证连通。B 对应的是不闭合的欧拉路径,C 中零度顶点与连通矛盾,D 只是边数与顶点数的偶然相等,与欧拉条件无关。就像洒水车要环游一圈,每个路口的进出路必须成双。
Q2. 柯尼斯堡七桥问题中,为什么“不重复走遍七座桥”的路线不存在?
- A.因为桥的总数是奇数
- B.因为四块陆地连接的桥数都是奇数← 正确答案
- C.因为河流太宽
- D.因为桥的长度不一样
答案:B。把四块陆地看作顶点,每块陆地连接的桥数分别是 5、3、3、3,四个全是奇数度顶点。欧拉路径要求奇数度顶点数为 0 或 2,这里却有 4 个,所以无解。桥总数是奇数并不妨碍欧拉回路存在,关键在于每个顶点进出配对的“度数”。
Q3. 哈密顿路径要求路线满足什么条件?
- A.经过每条边恰好一次
- B.经过每个顶点恰好一次← 正确答案
- C.经过每条边至少一次
- D.经过每个顶点至少一次
答案:B。哈密顿路径是“点任务”,要求每个顶点恰好访问一次,边可以不用完;欧拉路径才是“边任务”,要求每条边恰好经过一次。A 是欧拉的定义,C 和 D 分别是“中国邮路”和“覆盖问题”的变体,都不是哈密顿的准确表述。
Q4. 以下关于欧拉路径与哈密顿路径的陈述,哪些是正确的?
- A.欧拉路径经过图中每条边恰好一次← 正确答案
- B.哈密顿路径经过每个顶点恰好一次← 正确答案
- C.有欧拉回路的图一定是连通的← 正确答案
- D.有哈密顿回路的图一定有欧拉回路
答案:ABC。A 和 B 是两种路径的标准定义;C 正确,欧拉回路必须在连通图上才有意义。D 错误,哈密顿回路只管顶点不重复,不保证每条边恰好一次。例如五角星图有哈密顿回路但某些边可能多余,其度数条件未必成立。
Q5. 在 Fleury 算法中,“桥”指什么?
- A.图中长度最长的边
- B.删除后会使剩余图不再连通的边← 正确答案
- C.连接两个奇数度顶点的边
- D.权值最大的一条边
答案:B。桥是“独木桥”——删掉它,剩余图就分裂成两个互不相连的部分。Fleury 算法优先避开的正是这种边,防止走过后把自己困在孤岛上。C 是欧拉路径起点终点的特征,但不是桥的定义;A 和 D 与边长权重无关。
Q6. 判断一个图是否存在哈密顿路径,目前已知的复杂度属于哪种?
- A.线性时间 O(V+E)
- B.多项式时间 O(V²)
- C.NP 完全← 正确答案
- D.常数时间 O(1)
答案:C。哈密顿路径判定是第一批被证明的 NP 完全问题之一,目前没有已知多项式算法。欧拉判定才是线性时间,B 和 D 更是无从谈起。遇到“判断是否存在经过所有顶点一次的路径”这类题,第一时间想到指数级搜索,或借助特定图结构求特解。
Q7. 关于欧拉路径的存在条件,下列哪些说法正确?
- A.图中奇数度顶点数为 0 时,连通图存在欧拉回路← 正确答案
- B.图中奇数度顶点数为 2 时,连通图存在不闭合的欧拉路径← 正确答案
- C.图可以不连通,只要每个连通分量内满足度数条件
- D.图中奇数度顶点数为 4 时仍可能有欧拉路径
答案:AB。欧拉定理指出连通且奇数度顶点数为 0 得回路、为 2 得开路径,A 和 B 正确。C 错误,图必须整体连通,否则洒水车跨越不了断裂区域;D 错误,4 个奇度顶点无法配成一条连续的“一笔画”路线。
Q8. 欧拉路径问题与哈密顿路径问题在复杂度上的关键差异是什么?
- A.前者有线性或多项式算法,后者没有已知多项式算法← 正确答案
- B.后者有线性算法而前者没有
- C.两者都无法在多项式时间内判定
- D.两者难度完全相同
答案:A。欧拉判定 O(V+E)、构造 O(E²),属于典型的 P 类问题;哈密顿判定是 NP 完全,没有已知多项式算法。两者虽定义对称,复杂性却是一个在平地、一个在峭壁。正因为如此,工程中遇到问题要先判断“对象是边还是点”。
Q9. 关于欧拉路径与哈密顿路径的区别,下列哪些说法正确?
- A.欧拉路径针对边,哈密顿路径针对顶点← 正确答案
- B.欧拉路径的判定是简单问题,哈密顿路径是 NP 完全← 正确答案
- C.两者的求解复杂度在同一数量级
- D.欧拉回路必然同时是哈密顿回路
答案:AB。A 是任务对象的本质区别;B 是复杂度上的天壤之别;C 错误,一个多项式一个指数;D 错误,欧拉回路允许重复经过顶点,而哈密顿回路要求顶点不重复。例如一条“8”字形路线可重复走中心点,欧拉成立但哈密顿不成立,反之亦然。
Q10. 在完全图 K_n 中,考虑方向的哈密顿路径总共有多少条?
- A.n 条
- B.n! / 2 条
- C.n! 条← 正确答案
- D.2^n 条
答案:C。完全图任意两个顶点之间都有边,所以顶点的任何排列都自动构成一条哈密顿路径。n 个顶点的排列数是 n!,若方向视为相同则是 n!/2,但题目明确“考虑方向”,因此答案是 n!。这个例子说明哈密顿问题本质上是排列问题,排列数的增长速度决定了它的 NP 完全属性。