迪杰斯特拉算法的优化
在学习迪杰斯特拉算法之后,听说它可以被优化,但一直没有学习。
因为听到线段树,斐波那契堆就怕。
后面发现优先队列也可以实现优化,不过关于重载运算符那时候却没怎么懂现在终于会了。
我们在使用迪杰斯特拉算法的时候每次都要使用起点位置最短的点,如果每次都遍历的化时间复杂度会到达n^2。
于是我们就可以创建一个结构体记录它当前位置以及到达起点的距离,通过优先队列每次都取到达起点距离最小的点入队,时间复杂度便成了nlogn。
不说了粘代码。
#include<iostream> #include<queue> const int INF=0x7fffffff; using namespace std; int head[200005], now = 1, dis[100005],vis[100005]; bool book[100008]; struct edg { int nex, to, l; }edge[200005]; void add_edge(int at, int to, int l) { edge[now].nex = head[at]; edge[now].l = l; edge[now].to = to; head[at] = now++; } struct node { int at, dis; node(int a, int b) { at = a; dis = b; } bool operator <(const node& x)const//这里的引用&可有可无,不过为了规范最好加上 { return x.dis < dis; } }; int main() { int n, m, s; cin >> n >> m >> s; for (int i = 1; i <= m; i++) { int a, b, c; cin >> a >> b >> c; add_edge(a, b, c); } for (int i = 1; i <= n; i++) dis[i] = INF; dis[s] = 0; node now(s, 0); priority_queue <node> q; q.push(now); while (!q.empty()) { now = q.top(); q.pop(); if (vis[now.at]) continue; vis[now.at] = 1; for (int i = head[now.at]; i; i = edge[i].nex) { int x = edge[i].to; if (dis[x] > dis[now.at] + edge[i].l) { dis[x] = dis[now.at] + edge[i].l; if (!vis[x]) { node o(edge[i].to, dis[x]); q.push(o); } } } } for (int i = 1; i <= n; i++) cout << dis[i]<<" "; return 0; }
那么为了使用优先队列,我们在结构体中加了个重载运算符的操作。
c++允许对运算符进行重载,比如为了使结构体相加,我们不需要写一个函数,只要重新为+号做一个定义就可以了。
而operator就是运算符重载的关键字。
这里我们进行了<号的重载,使得优先队列知道应该将dis较小的node放在前面。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix