最短路径问题---Dijkstra算法详解
0. 最短路径问题介绍
问题解释:
从图中的某个顶点出发到达另外一个顶点的所经过的边的权重和最小的一条路径,称为最短路径
1. Dijkstra算法介绍
-
算法特点:
迪科斯彻算法使用了广度优先搜索解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树。该算法常用于路由算法或者作为其他图算法的一个子模块。
-
算法的思路
Dijkstra算法采用的是一种贪心的策略
需要声明一个数组
以及一个集合 表示源点到节点 的最短距离 中存储已经找到了最短路径的节点初始时,源点
的路径权重被赋为 0 。若对于节点 存在能直接到达的边 ,则把 设为 ,同时把所有其他( 不能直接到达的)节点的路径长度设为无穷大。初始时,集合 只有顶点 。然后,从
数组选择最小值,则该值就是源点 到该值对应的顶点的最短路径,并且把该点加入到 中,OK,此时完成一个顶点。接着我们需要看看新加入的顶点是否可以到达其他顶点并且看看通过该顶点到达其他点的路径长度是否比当前的最短路径短,如果是,那么就替换这些顶点在
中的值。然后,又从
中找出最小值,重复上述动作,直到 中包含了图的所有顶点。
3、Dijkstra算法示例演示
求下图,从顶点
首先第一步,我们先声明一个dis数组,该数组初始化的值为(下标从1开始):
下标 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
dis | 0 | ∞ | 10 | ∞ | 30 | 100 |
我们的
既然是求
为什么呢?因为目前离
OK,既然确定了一个顶点的最短路径,下面我们就要根据这个新入的顶点
下标 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
dis | 0 | ∞ | 10 | 60 | 30 | 100 |
然后,我们又从除
下标 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
dis | 0 | ∞ | 10 | 50 | 30 | 90 |
然后,继续从
下标 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
dis | 0 | ∞ | 10 | 50 | 30 | 60 |
然后,我们使用同样原理,分别确定了
下标 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
dis | 0 | ∞ | 10 | 50 | 30 | 60 |
因此,从图中,我们可以发现
4、Dijkstra算法代码实现:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=7010;
struct node{
int i;
int k;
bool operator < (node a) const{
return k>a.k;
}
};
int n,m,s;
ll dis[maxn];
bool T[maxn];
priority_queue<node> q;
int head[maxn],to[2*maxn],nxt[2*maxn],w[2*maxn],cnt=1;
void add(int x,int y,int v){
cnt++;
to[cnt]=y;
w[cnt]=v;
nxt[cnt]=head[x];
head[x]=cnt;
}
int main(){
cin>>n>>m>>s;
for(int i=1,x,y,v;i<=m;i++){
cin>>x>>y>>v;
add(x,y,v);
add(y,x,v);
}
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
q.push(node{s,0});
while(q.size()){
node h=q.top();
int p=h.i;
q.pop();
if(T[p]) continue;
T[p]=true;
for(int i=head[p];i;i=nxt[i]){
if(dis[p]+w[i]<dis[to[i]]&&!T[to[i]]){
dis[to[i]]=dis[p]+w[i];
q.push(node{to[i],dis[to[i]]});
}
}
}
for(int i=1;i<=n;i++){
if(dis[i]==0x3f3f3f3f3f3f3f3f) printf("-1\n");
else printf("%lld\n",dis[i]);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效