Dijkstra 算法(2)
Dijkstra 算法(2)
1.例题
题目描述
给定一个
请你求出 −1
。
输入格式
第一行包含整数
接下来
输出格式
输出一个整数,表示
如果路径不存在,则输出 -1
。
数据范围
图中涉及边长均不小于
数据保证:如果最短路存在,则最短路的长度不超过
输入样例:
3 3 1 2 2 2 3 1 1 3 4
输出样例:
3
注:本题来源于AcWing题库第850题
2.思路
没学过 dijkstra 算法的请到这里去。
首先,我们先来观察一下题目,
很明显,dijkstra 算法
这时我们就需要进行优化了。
在寻找一个未标记且最近的点(下面我们把这个点叫做
那我们要在众多数中找一个最小值,能不能用堆来优化呢?
堆排序的时间复杂度为
所以,我们便可以在每次用
这就是优化!
3.代码
本人用的是优先队列,用手写太麻烦了,我相信没多少人会故意去把代码往难里写。
#include<iostream> #include<cstring> #include<queue> using namespace std; const int N=150005; int n,m; int w[N],h[N],e[N],ne[N],idx; int dist[N]; bool st[N]; struct node{ int first,second;//代表距离和编号 bool operator < (const node &x) const{//重载运算符 return first>x.first; } }; void add(int a,int b,int c){//用邻接表存储的加边操作 e[idx]=b; w[idx]=c; ne[idx]=h[a]; h[a]=idx++; } int dijkstra(){ memset(dist,0x3f,sizeof(dist)); dist[0]=1; priority_queue<node> heap; node a={0,1};//先用1号点初始一下距离 heap.push(a); while(heap.size()){//判断堆不空也就是看点没有遍历完 node t=heap.top(); heap.pop(); int ver=t.second,distance=t.first; if(st[ver]) continue;//如果已经遍历过了就证明是一个冗余备份,直接跳过 st[ver]=true; for(int i=h[ver];i!=-1;i=ne[i]){//遍历所有t的能到达的点 int j=e[i];//遍历到的这个点到t点的距离 if(dist[j]>distance+w[i]){ dist[j]=distance+w[i]; node p={dist[j],j};//如果老距离大于新距离就更换并入堆 heap.push(p); } } } if(dist[n]==0x3f3f3f3f) return 0x3f3f3f3f; } int main(){ cin>>n>>m; memset(h,-1,sizeof h); for(int i=1;i<=m;i++){ int a,b,w; cin>>a>>b>>w; add(a,b,w); } if(dijkstra()==0x3f3f3f3f) cout<<"-1"; else cout<<dist[n]; return 0; }
当然,如果不想写重载运算符也可以去补齐小根堆的两个参数。
完~
如果觉得还不错,就点个赞吧,您的支持就是我最大的动力。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】