单源最短路 - Dijkstra 算法 / SPFA 算法
Dijkstra(迪杰斯特拉)算法是基于贪心思想的单源最短路算法
暴力 Dijkstra
具体如下:
struct node { int v, w; };
vector<node> e[N];
int dist[N], vis[N];
e[u] 存的是节点 u 的所有出边的终点和边权,dist[u] 存 u 到原点 s 的最小距离, vis[u] 标记是否走过
void dijkstra(int s) {
memset(dist, 0x3f, sizeof dist); // 初始先让所有点设为 +∞
dist[s] = 0; // 原点离自身距离为0
for(int i = 1; i < n; i ++) { // 枚举次数
int u = 0;
for(int j = 1; j <= n; j ++) { // 枚举点
if(!vis[j] && dist[j] < dist[u]) u = j; // 选择一个距离最小的标记
}
vis[u] = 1;
for(auto ed : e[u]) { // 对u的所有出边,更新邻边v的最小距离
int v = ed.v, w = ed.w;
if(dist[v] > dist[u] + w) dist[v] = dist[u] + w;
}
}
}
主函数:
int main() {
cin >> n >> m >> s;
for(int i = 0; i < m; i ++) {
cin >> a >> b >> c;
e[a].push_back({b, c}); // 加入a的邻边b和权值c
}
dijkstra(s);
return 0;
}
但是以上的方法对于负边权不适用,会出错;
并且时间复杂度为
对于
Dijkstra 算法的堆优化 ---- 用优先队列维护被更新的点的集合
Heap - Dijkstra
具体如下:
priority_queue<pair<int, int>> q;
创建一个pair类型的大根堆 q{-距离, 点},或者是 小根堆 q{距离, 点}; 但小根堆需要自己用结构体加重载运算符
小根堆写法:
点击查看代码
struct node
{
int first; // 距离
int second; // 点编号
bool operator <(const node &x)const // 重载运算符
{
return x.first<first;
}
};
priority_queue<node> q;
void dijkstra(int s) {
memset(dist, 0x3f, sizeof dist);
dist[s] = 0;
q.push({0, s}); // 原点入队
while(q.size()) {
auto t = q.top();
q.pop();
int u = t.second; // 从队头弹出距离最小的点u
if(vis[u]) continue; //如果走过就直接出队
vis[u] = 1; //没走过标记下
for(auto ed : e[u]) {
int v = ed.v, w = ed.w;
if(dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
q.push({-dist[v], v}); // 把更小的点及距离入队
}
}
}
}
SPFA 算法
- 用于处理负边权的情况
具体如下:
void spfa(int s) {
memset(d, 0x3f, sizeof d);
d[s] = 0, vis[s] = 1;
q.push(s);
while(q.size()) {
auto u = q.front();
q.pop();
vis[u] = 0;
for(auto ed : e[u]) {
int v = ed.v, w = ed.w;
if(d[v] > d[u] + w) {
d[v] = d[u] + w;
if(!vis[v]) q.push(v), vis[v] = 1; // v点被更新且不在队内,则入队
}
}
}
}
- 时间复杂度:
总结:
暴力 Dijkstra | Heap - Dijkstra | SPFA | |
---|---|---|---|
时间复杂度 | |||
图的大小 | 稠密图 |
稀疏图 |
稠密图 |
负边权 | 不能 | 不能 | 能 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】