📘 一、问题定义
给定一个有向图(多段图),从顶点 0(源点)出发,到顶点 n-1(终点),每条边有权重,求一条路径使得路径权重和最小,并输出路径。
输入用代价矩阵 arc[i][j] 表示:从顶点 i 到 j 的路径权值,不存在边则为 ∞(或 1000)。
🧠 二、关键变量定义
| 变量 | 含义 |
|---|---|
cost[j] | 从源点 0 到顶点 j 的最短路径长度 |
path[j] | 最短路径中到达 j 前一步的顶点编号 |
arc[i][j] | 从顶点 i 到 j 的代价(权重) |
🔧 三、代码执行逻辑详解
✅ 初始化
cost[0] = 0; // 源点出发,代价为 0
path[0] = -1; // 源点没有前驱
✅ 主循环(正向 DP)
for (j = 1; j < n; j++) { // 依次计算从 0 到 j 的最短路径
cost[j] = 1000; // 初始设为无穷
for (i = 0; i < j; i++) { // 找所有可能到 j 的前驱 i
if (cost[i] + arc[i][j] < cost[j]) {
cost[j] = cost[i] + arc[i][j];
path[j] = i; // j 最优前驱是 i
}
}
}
这个是从源点 0 出发,一段一段地更新到每个点的最小花费。
✅ 回溯路径(逆向找 path)
cout << --n; // 输出终点
for (i = n; path[i] >= 0; ) {
cout << "<--" << path[i];
i = path[i]; // 一直找回前驱
}
从终点往前,按照 path[j] 找路径上的前一个点,直到源点。
🧮 四、例子演示
举个小例子:
arc = [
[∞, 2, 4, ∞],
[∞, ∞, 1, 7],
[∞, ∞, ∞, 3],
[∞, ∞, ∞, ∞]
]
路径为 0→1→2→3,总权重 2+1+3=6,为最短。
⏱ 五、时间复杂度分析
-
外层
j循环 n 次 -
内层
i最多 n 次 -
总体复杂度:O(n²)
✅ 总结核心思想
| 步骤 | 说明 |
|---|---|
| 初始化 | 源点 cost[0]=0,其余设为无穷 |
| 状态转移 | 遍历所有 i < j 的路径,找最小 cost[i] + arc[i][j] |
| 路径记录 | 用 path[j] 存最优前驱,辅助回溯路径 |
| 回溯输出路径 | 从 n-1 开始,一直找 path[j],直到回到 0 |
&spm=1001.2101.3001.5002&articleId=148779301&d=1&t=3&u=99fa5ebb4e6c4563a0a3eecd532790ef)
4223

被折叠的 条评论
为什么被折叠?



