专栏文章
题解:P4779 【模板】单源最短路径(标准版)
P4779题解参与者 6已保存评论 5
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @mioscqhw
- 此快照首次捕获于
- 2025/12/03 00:21 3 个月前
- 此快照最后确认于
- 2025/12/03 00:21 3 个月前
Solution
update on 2025.8.12:ED_BuilderSolusion->Solution。
思路
使用博客园效果更佳。
首先,题目说的很明白,这个广为人知的最短路算法就是 SPFA,它死了。这题会专门卡 SPFA,别问我咋知道的,在最劣情况下 SPFA 时间复杂度 ,边权没有负数的情况下我们通常使用 dijkstra 算法,而在有负边权的情况下通常使用 Bellman-Ford。
这题和简单版的唯一区别就是简单版可以 ,然而这题需要使用更优的时间复杂度。
dijkstra 的实现过程:
用一个
queue 维护我们可以走到的点,dis[u] 表示从起点走到 点的最短路径,我们每次遍历当前节点 可以走到的节点 ,若从 走到 节点更优,则更新 的最短路,由于我们可以从 节点走到 节点,将 节点丢入 queue 中。我们可以举个例子:

| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| queue | 1 | |||
| dis | 0 |
初始时没有任何操作。
然后从起点遍历,点 至点 的边权为 ,先遍历到了点 ,发现我们从点 到点 最优,则更新从起点到点 的最短路,然后丢入队列。
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| queue | 2 | |||
| dis | 0 | 2 |
遍历到了点 ,点 至点 的边权为 ,发现我们从点 到点 最优,则更新从起点到点 的最短路,然后丢入队列。
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| queue | 2 | 3 | ||
| dis | 0 | 2 | 3 |
然后点 到不了其他点了,所以将队列的第一个元素点 拿出来进行遍历。
从节点 只能遍历到点 ,且可以更新最短路,丢入队列。
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| queue | 3 | 4 | ||
| dis | 0 | 2 | 3 | 6 |
点 到不了其他点了,所以将队列的第一个元素点 拿出来进行遍历。
从节点 只能遍历到点 ,原最短路是 ,然而从点 去点 只要 ,可以更新最短路,丢入队列。
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| queue | 4 | |||
| dis | 0 | 2 | 3 | 4 |
然后把点 拿出来,不能遍历,跳过。
队列空了,结束。
最终结果:
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| queue | ||||
| dis | 0 | 2 | 3 | 4 |
但是为什么不能处理负边权?
因为 dijkstra 基于贪心思想,遍历到一次的节点不会再次更新。
上面的过程是 dijkstra 的朴素做法,复杂度 ,所以我们需要堆优化。
由于 dijkstra 是基于贪心的算法,因此我们可以用
priority_queue 优化。注意事项:
- 由于我们 要取 值,所以 初始化为一个极大值,通常为 。
- 题目是有向边。
代码:
CPPvoid dijkstra(int s)
{
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
memset(dis, 0x3f, sizeof(dis)); // 初始化
dis[s] = 0;
q.push({dis[s], s}); // 将起点加入队列
while (!q.empty())
{
int u = q.top().second;
q.pop();
if (vis[u]) // 若 u 已访问,跳过
continue;
vis[u] = true; // 标记为已访问
for (int j = 0; j < adj[u].size(); j++) // 遍历 u 可以去的所有点
{
int v = adj[u][j].to, w = adj[u][j].w;
if (dis[v] > dis[u] + w) // 若从 u 去 v 更优,更改最短路,丢进队列
{
dis[v] = dis[u] + w;
q.push({dis[v], v});
}
}
}
}
相关推荐
评论
共 5 条评论,欢迎与作者交流。
正在加载评论...