dijkstra 单源最短路算法 学习笔记
思想
利用贪心,BFS。
首先确定一个起始点
需要两个数组
做法:从 起始点
更新完毕之后,查找所有
重复这个过程,直到所有的点都被打上了
特性
不适用于有负边权的图中。
根据上面的 dijkstra 单源最短路求解过程,我们发现整个过程都是基于贪心的思想,找到当前
但,接下来的边权一定还会让该路径的长度变长吗?如果接下来的边权是负数的话,就可能存在更短的路径了。这也就验证了为什么 dijkstra 算法不适用于有负边权的图中。
例如:在下面这个图中,我们若想求从
首先起始点为
但如果没有负边权,毫无疑问 dijkstra 的做法是完全正确的,因为无论如何其他的路径都无法再减少长度了。
代码
我们令一个图中的点的个数为
按照当前的思路来看,我们对每个点进行遍历,复杂度为
每次寻找所有
对每条边都要进行一次松弛操作,复杂度为
故总的时间复杂度为
考虑堆优化,使用优先队列,考虑到我们可以将优先队列更改为小根堆,每次取出队头的元素就是最小值,那么我们查找最小值的操作复杂度可以优化为
再用邻接表代替邻接矩阵,最终复杂度可以达到
代码实现:
struct point{
int id,dis;
friend bool operator < (point a,point b){
return a.dis > b.dis;
}
};
priority_queue<point> q;
int dist[N];
bool vis[N];
void dijkstra(){
memset(dist,0x3f,sizeof(dist));
dist[s] = 0;
q.push((point){s,0});
while (!q.empty()){
int tmp = q.top().id;
q.pop();
if (!vis[tmp]){
vis[tmp] = 1;
for (int i = head[tmp];i;i = e[i].nxt){
int v = e[i].to;
int w = e[i].w;
if (dist[v] > dist[tmp] + w){
dist[v] = dist[tmp] + w;
q.push((point){v,dist[tmp] + w});
}
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】