一 真题2009-41
2009-41题. (10分)带权图(权值非负,表示边连接的两顶点间的距离)的最短路径问题是找出从初始顶点到目标顶点之间的一条最短路径。假设从初始顶点到目标顶点之间存在路径,现有一种解决该问题的方法:
-
设最短路径初始时仅包含初始顶点,令当前顶点u为初始顶点;
-
选择离u最近且尚未在最短路径中的一个顶点v,加入最短路径中,修改当前顶点u=v;
-
重复步骤2,直到u是目标顶点时为止。
请问上述方法能否求得最短路径?若该方法可行,请证明之;否则,请举例说明。
二 题目要素解析
场景: 带权图的单源最短路径问题。
核心概念:
- 贪心算法:每一步都做出局部最优的选择。
- Dijkstra 算法:全局贪心,每次从未确定顶点中选出到源点距离最短的点。
- 题目算法 :局部贪心,每次从当前顶点 出发,选择直接相邻且最近的未访问点。
求: 该方法是否正确?
核心考点: 最短路径算法的正确性判断,考察对 Dijkstra 算法与 "贪心策略陷阱" 的理解。
三 哔哔详解
这道题考察的是对算法逻辑的严密分析能力。很多同学乍一看觉得像 Dijkstra 算法,但其实两者有本质区别。
-
分析算法逻辑:
- 题目中的算法是一种 "最邻近点优先" 的策略。
- 它的逻辑是:"走一步看一步,每次只走离我现在位置最近的路"。
- 这是一种短视的贪心。它没有考虑到 "虽然下一步路远一点,但后面的路会非常近" 的情况。
-
Dijkstra 算法的逻辑(对比):
- Dijkstra 算法每次选的是 "从源点出发,目前已知距离最短" 的点(可能是经过多步跳转的)。
- Dijkstra 是全局 最优,而题目算法是局部最优。
-
构造反例:
- 我们需要构造一个图,使得 "走最近的一步" 反而导致 "总路程变长"。
反例如下:
- 顶点: A(源点),B(中间点),C(目标点)。
- 边权:
- A -> B:长度为 1。
- B -> C:长度为 100。
- A -> C:长度为 10。
执行题目算法:
- 起点 A。
- 看 A 的邻居:B (1) 和 C (10)。
- 选择最近的 B。
- 到达 B,此时 B 是当前顶点。
- 看 B 的邻居:C (100)。
- 选择 C。
- 总路径: A -> B -> C,总长度 = 1 + 100 = 101。
实际最短路径:
- 直接走 A -> C,总长度 = 10。
结论: 101 > 10,算法求得的不是最短路径。
四 参考答案
该方法不能求得最短路径。
举例说明如下:
假设有带权无向图 G=(V,E),其中顶点集 V={A,B,C},边集 E={(A,B,1),(B,C,100),(A,C,10)}。
设初始顶点为 A,目标顶点为 C。
- 按照题目方法执行:
- 初始时,路径为 {A},当前顶点 u=A。
- 考察 A 的邻接点:B(距离 1)和 C(距离 10)。
- 选择离 A 最近的顶点 B 加入路径。路径变为 {A,B},当前顶点 u=B。
- 考察 B 的邻接点(未在路径中的):C(距离 100)。
- 选择 C 加入路径。路径变为 {A,B,C}。
- 此时 u 是目标顶点,算法结束。
- 求得路径长度为 1+100=101。
- 实际最短路径:
- 直接从 A 到 C,路径长度为 10。
由于 101不等于10,因此该方法不能保证求得最短路径。
五 考点精析
5.1 贪心算法(Greedy Algorithm)
1 概念
贪心算法是一种在每一步都做出局部最优选择,从而希望最终得到全局最优解的算法策略。
2 核心思想
- 每一步选 "看起来最好" 的
- 不回溯、不后悔
- 只考虑当前,不考虑全局
3 特点
- 简单、高效
- 不一定能得到全局最优解
- 只有问题具有 "贪心选择性质" 和 "最优子结构" 时才正确
4 典型应用
- 活动选择问题
- 哈夫曼编码
- 最小生成树(Prim、Kruskal)
- 部分背包问题
5.2 Dijkstra 算法
1 概念
Dijkstra 算法是一种求解带权图中单源最短路径的经典算法。
2 核心思想
- 从源点出发,每次选择当前已知距离源点最近的未确定顶点
- 将其加入 "已确定最短路径集合"
- 然后更新其邻接点的距离
- 重复直到所有顶点处理完毕
3 特点
- 基于贪心策略,但能保证得到全局最优解
- 要求边权非负
- 时间复杂度:O (V²) 或 O (E log V)(用堆优化)
4 本质
Dijkstra = 贪心 + 最优子结构 + 动态规划思想的特例
5.3 两者区别
| 维度 | 贪心算法(泛指) | Dijkstra 算法 |
|---|---|---|
| 范畴 | 一类算法设计策略 | 一个具体算法 |
| 决策依据 | 通常基于局部信息(如当前点的邻居) | 基于全局已知的最短估计(所有未访问点中最小) |
| 是否回溯 | 不回溯(一旦选择,永不更改) | 不回溯,但通过松弛操作动态更新估计值 |
| 适用范围 | 仅对满足贪心选择性质的问题有效 | 仅适用于非负权图的单源最短路径 |
| 反例存在性 | 很多问题贪心失败(如本题 2009-41) | 在非负权图中总能得到最优解 |
5.4 高频考点辨析
| 问题 | 正确认知 |
|---|---|
| "Dijkstra 是贪心算法吗?" | ✅ 是,但属于有全局信息支撑的贪心 |
| "所有贪心都能解最短路径?" | ❌ 否,仅当图满足特殊结构(如树)时可能成立 |
| "Dijkstra 能处理负权边吗?" | ❌ 不能(会破坏贪心选择的正确性) |
| "Prim 和 Dijkstra 形式相似,有何区别?" | Prim:选到集合最近的点;Dijkstra:选从源点最近的点 |
六 考点跟踪
| 年份 | 题号 | 考查内容 | CSDN 参考链接 | VX参考链接 |
|---|---|---|---|---|
| 2009 | 第41题 | 贪心算法 | ||
| 2012 | 第7题 | Dijkstra | ||
| 2018 | 第42题 | Dijkstra | ||
| 2021 | 第8题 | Dijkstra |
说明 :本文内容基于公开资料整理,参考了包括但不限于《数据结构》(严蔚敏)、《计算机操作系统》(汤小丹)、《计算机网络》(谢希仁)、《计算机组成原理》(唐朔飞)等国内高校经典教材,以及其他国际权威著作。同时,借鉴了王道、天勤、启航等机构出版的计算机专业考研辅导系列丛书 中的知识体系框架与典型题型分析思路。文中所有观点、例题解析及文字表述均为作者结合自身理解进行的归纳与重述,未直接复制任何出版物原文。内容仅用于学习交流,若有引用不当或疏漏之处,敬请指正。