dijkstra算法详解
今天给大家讲解
在讲解
松弛,即
举例说明,例如我们可以从某个机场坐飞机达到若干个机场,然后从这些机场出发,我们又需做火车前往若干个城镇。现在假设我们手里有飞行时间表(
C[v] = float('inf')
for u in A:
C[v] = min(C[v], A[u]+B[u][v]) //
松弛法(relaxation)是一数学术语,描述的是一些求解方法,这些方法会通过逐步接近的方式获得相关问题的最佳解法。每运用一次松弛法就好像我们“移动”了一次,而我们要做的就是在尽可能少的移动次数内找到最佳解决方案。
理论上来说,我们可以在整个空间上运用相关的松弛法,但关键在于找到一个正确的执行次序。
讲完了松弛法,接下来就给大家讲解
(1). 算法解决问题范围
且路径的权值不为负权。
(2). 算法思想及原理
(3). 算法描述
我们假设现在要求出
首先将
然后运用
接着找出在未知集合中里找出距离
最后就重复以上流程
(4). 算法具体流程
(5). 算法的优化
我们发现,普通的
(6). 算法核心代码
优化前:
void Dijkstra(int k1)
{
//vis为已知集合,dis表示k1到其他点的最小距离
memset(dis,0x3f,sizeof(vis));
vis[k1]=1;
dis[k1]=0;
for(int i=1;i<m;++i)
{
for(int j=fst[k1];j;j=arr[j].nxt)//链式前向星
{
//松弛
int tmp=arr[j].u;
if(dis[k1]+arr[j].v<dis[tmp])
{
dis[tmp]=dis[k1]+arr[j].v;
last[tmp]=k1;
}
}
int mid=0x3f3f3f3f;
//寻找距离起点最小的点
for(int j=1;j<=m;++j)
{
if(vis[j]==0&&dis[j]<mid)
mid=dis[j],k1=j;
}
vis[k1]=1;
}
}
优化后:
dis[s]=0;
q.push(make_pair(0,s));
while(!q.empty())//排序规则请运用结构体重载自己设定,这里不做阐述
{
int x=q.top().second;//取出点
q.pop();
if(vis[x]==1)//如果这个点已经被压入队列过,不执行这一次循环。
continue;
vis[x]=1;
//松弛
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to,z=e[i].w;
if(dis[x]+z<dis[y])
{
dis[y]=dis[x]+z;
q.push(make_pair(-dis[y],y));//将所有距离和点压入队列
}
}
}
(7). 算法时间复杂度
普通
优化后的
(8). 输出路径
dis[s]=0;
q.push(make_pair(0,s));
while(!q.empty())
{
int x=q.top().second;
q.pop();
if(vis[x]==1)
continue;
vis[x]=1;
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to,z=e[i].w;
if(dis[x]+z<dis[y])
{
dis[y]=dis[x]+z;
last[y]=x;
q.push(make_pair(-dis[y],y));
}
}
}
void print(int t)
{
if(last[t])
print(last[t]);
cout<<t<<" ";
}
以上就是 算法的全部内容了,希望大家有所收获
参考资料:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探