1. 最短路径算法概述
在计算机科学和算法设计中,最短路径问题是一个经典且重要的问题。它要求我们找到图中两个顶点之间路径权值之和最小的路径。这个问题在实际应用中无处不在,从地图导航到网络路由,从物流规划到社交网络分析,都需要高效的最短路径算法。
最短路径算法主要分为两类:单源最短路径算法和多源最短路径算法。单源算法计算从一个特定起点到图中所有其他顶点的最短路径,而多源算法则计算图中任意两个顶点之间的最短路径。Dijkstra算法和Floyd算法分别是这两类算法中最具代表性的解决方案。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Dijkstra算法详解
2.1 算法原理与核心思想
Dijkstra算法由荷兰计算机科学家Edsger W. Dijkstra于1956年提出,是一种解决单源最短路径问题的经典算法。它的核心思想是贪心策略:每次从未处理的顶点中选择距离起点最近的顶点,然后更新其邻居的距离。
算法要求图中所有边的权值必须为非负数。这是因为Dijkstra算法基于贪心策略,假设当前最短路径就是全局最短路径,而负权边会破坏这一假设。
注意:Dijkstra算法不能处理包含负权边的图。如果图中存在负权边,应考虑使用Bellman-Ford算法。
2.2 堆优化实现细节
原始Dijkstra算法的时间复杂度为O(V²),通过使用优先队列(堆)优化,可以将时间复杂度降低到O(ElogV),其中V是顶点数,E是边数。
以下是堆优化Dijkstra的关键实现步骤:
-
数据结构准备:
- 邻接表存储图结构
- 距离数组记录起点到各顶点的最短距离
- 访问标记数组避免重复处理
- 优先队列(小顶堆)用于高效获取当前最小距离顶点
-
算法流程:
- 初始化:起点距离设为0,其他顶点设为无穷大
- 将起点加入优先队列
- 循环处理队列直到为空:
- 取出当前距离最小的顶点
- 标记为已访问
- 松弛操作:更新其邻居顶点的距离
2.3 完整代码实现与解析
cpp复制#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct cmp {
bool operator()(const pair<ll,ll>& a, const pair<ll,ll>& b) {
return a.second > b.second;
}
};
ll inf = 2147483647;
int n,m,s;
vector<int> vis;
vector<vector<pair<ll, ll>>> e;//存边和权
vector<pair<ll,ll>> g;//存距离和上一个节点
void dijk(int s) {
priority_queue<pair<ll,ll>, vector<pair<ll,ll>>,
