概述
定义
Dijkstra算法 是由荷兰计算机科学家狄克斯特拉于1959年提出的,用于解决带权图 的单源最短路径问题。该算法采用贪心 策略,每次选择当前距离起点最近 且未访问 过的顶点,逐步扩展到终点。
时间复杂度
这个在于你的优化程度,我的是\(O(mlogn)\)
核心内容
在边权都不为负的前提下:
- 先把起点到自己的距离设为 0,其他点都设为无穷远。
- 每次在还没确定最短路 的点里,选出离起点最近的那个点。
- 这个点的最短距离就固定了,不会再变。
- 再用这个点去更新它相邻点的距离,看看能不能走得更近。
- 重复直到所有点都确定完毕。
代码解析
cpp
#include <bits/stdc++.h>
using namespace std;
constexpr int N = 1e5 + 2;
vector<pair<int, int>> a[N]; // {能到的边,这两个边的边权}
int d[N]; // 当前的最短路,执行过程中可能多次修改
bool f[N]; // 还可不可能再被更新,true是不可以
inline void dij(int s) {
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; // 小的在前面
memset(d, 127, sizeof d); // 初始化极大值
d[s] = 0; // 原点到自己的距离为0
q.push({0, s}); // {这时的最短距离(不一定是最终的),点的编号}
while (!q.empty()) {
auto p = q.top();
q.pop();
int now = p.second; // 查找now点的可以更新临边
if (f[now]) continue; // 判断是否可能更优
f[now] = true; // 设为最优,不用更新
for (auto i : a[now]) { // 遍历可以直接到达的点
int x = i.first, y = i.second;
if (d[x] > d[now] + y) { // 判断是否可能更优
d[x] = d[now] + y; // 更新
q.push({d[x], x}); // 入队
}
}
}
}
signed main() {
int n, m, s;
cin >> n >> m >> s;
for (int i = 1; i <= m; i++) {
int u, v, w;
cin >> u >> v >> w;
a[u].push_back({v, w});
}
dij(s);
for (int i = 1; i <= n; i++) {
cout << d[i] << " "; // 输出到每一个点的最短距离
}
return 0;
}
听懂?点赞?