最短路三种算法详解
最短路
最短路问题即,给你一张图,让你求出图中两点的最短距离。
这篇文章会讲解
Dijkstra#
朴素版#
题目:
我们用
还需要维护一个状态数组
在每一次扩展的过程中,我们要先找到当前未确定的点的集合中找到一个距离最小的点,也就是:
int t = -1; // 距离最短的点的编号
for (int j = 1; j <= n; ++j)
if (!st[j] && (t == -1 || dist[j] < dist[t])) // 判断是否符合条件
t = j;
那么我们就已经确定这个点了,把它的状态更新一下:
st[t] = true;
然后用这个点更新所有未确定点的最短距离
for (int j = 1; j <= n; ++j)
if (!st[i]) // 这句话其实可以不用加,因为我们dijkstra算法的性质已经确定后面确定的点不会再比现在的小了
dist[j] = min(dist[j], dist[t] + g[t][j]);
完整代码:
#include <iostream>
#include <cstring>
#define N 510
using namespace std;
int n, m;
int g[N][N];
int dist[N];
bool st[N];
int dijkstra() {
memset(dist, 0x3f, sizeof dist);
dist[1] = 0; // 源点到源点的距离是0
for (int i = 1; i <= n; ++i) {
int t = -1;
for (int j = 1; j <= n; ++j)
if (!st[j] && (t == -1 || dist[j] < dist[t]))
t = j;
st[t] = true;
for (int j = 1; j <= n; ++j) dist[j] = min(dist[j], dist[t] + g[t][j]);
}
if (dist[n] == 0x3f3f3f3f) return -1; // 不存在最短路径
return dist[n];
}
int main() {
memset(g, 0x3f, sizeof g);
cin >> n >> m;
while (m--) {
int a, b, c;
cin >> a >> b >> c;
g[a][b] = min(g[a][b], c); // 防止重边的情况
}
cout << dijkstra() << '\n';
return 0;
}
此代码时间复杂度为
优化#
我们发现,朴素
于是我们的代码就可以优化成这样了:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define N 200000
typedef pair<int, int> PII; // 存储距离和节点编号
int n, m;
int h[N], e[N], w[N], ne[N], idx; // 因为是点数较多,所以用邻接表存图
int dist[N];
bool st[N];
void add(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++; }
int dijkstra() {
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
priority_queue<PII, vector<PII>, greater<PII>> q;
q.push({0, 1});
while (q.size()) {
auto t = q.top();
q.pop();
int ver = t.second;
if (st[ver]) continue;
st[ver] = true;
for (int i = h[ver]; i != -1; i = ne[i]) {
int j = e[i];
if (dist[j] > dist[ver] + w[i]) {
dist[j] = dist[ver] + w[i];
q.push({dist[j], j});
}
}
}
if (dist[n] == 0x3f3f3f3f) return -1;
return dist[n];
}
int main() {
memset(h, -1, sizeof h);
cin >> n >> m;
while (m--) {
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
}
cout << dijkstra() << '\n';
return 0;
}
剩下的咕咕,明天再写。都咕两个月了还没补
作者:chinjinyu
出处:https://www.cnblogs.com/popfront/p/17659405.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库