最短路: Djikstra

最短路: Djikstra


  • 适用于边权非负

    如果存在负边权, 则当前距离dist最小的点, 不一定就是实际离源点最近的点,可能有负边导致其它路径离当前点更近

    如下图所示, 如果存在负边, y点距离S点最近, 所以选中y点进行松弛,

    image-20230821111655979
  • 贪心思想

  • 当边权非负,离起点S最近的点,不能被更新, 如果在中间加入一个点,则长度必然大于当前距离

  • 在稀疏图中.使用二叉堆实现的 Dijkstra 算法较 Bellman-Ford 算法具有较大的效率优势;

  • 而在稠密图中,这时候使用暴力做法较二叉堆实现更优。

最短路

  • 暴力
  • 时间复杂度
    • 不使用任何数据结构进行维护,每次 2 操作执行完毕后,直接在 集合中暴力寻找最短路长度最小的结点。2 操作总时间复杂度为 ,1 操作总时间复杂度为 ,全过程的时间复杂度为 。
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 5e3+5;
const int INF = 0x3f3f3f3f;
int dist[N];
bool distOver[N];
vector<PII> edges[N];
int n, m, k;
void djikstra(int s, int t) {memset(dist, 0x3f, sizeof(dist));memset(distOver, false, sizeof(distOver));dist[s] = 0;for (int i = 1; i <= n; i++) {int u = -1;for (int j = 1; j <= n; j++) {if (!distOver[j] && dist[j] < INF) {if (u == -1 || dist[j] < dist[u]) {u = j;}}}if (u == -1) break;distOver[u] = true;for (auto [v, w] : edges[u]) {dist[v] = min(dist[v], dist[u] + w);}}if (dist[t] < INF) cout << dist[t] << endl;else cout << -1 << endl;}
int main() {cin >> n >> m >> k;while (m--) {int u, v, w;cin >> u >> v >> w;edges[u].push_back({v, w});}while (k--) {int s, t;cin >> s >> t;djikstra(s, t);}return 0;
}

最短路2


堆优化

使用升序排列的优先队列

distOver[u]表示结点u的距离已经确定

每从堆中取出最近的点, 则S到这个点的最短距离已经确定

再从这个点开始尝试松弛, 其它未确定的点的距离

  • 时间复杂度

    和二叉堆类似,但使用优先队列时,如果同一个点的最短路被更新多次,因为先前更新时插入的元素不能被删除,也不能被修改,只能留在优先队列中,故优先队列内的元素个数是O(m)的,

    时间复杂度为 O ( m ∗ l o g m ) O(m*logm) O(mlogm)

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5+5;
const int INF = 0x3f3f3f3f;
bool distOver[N];
int dist[N];
vector<pair<int, int>> edge[N];
void Djikstra(int s, int t) {memset(dist, 0x3f, sizeof(dist));memset(distOver, false, sizeof(distOver));priority_queue<PII, vector<PII>, greater<PII>> q;dist[s] = 0;q.push(make_pair(dist[s], s));while (!q.empty()) {int u = q.top().second; q.pop();if(distOver[u]) continue;distOver[u] = true;for(auto [v, w] : edge[u]) {if(dist[u] + w < dist[v]) {dist[v] = dist[u] + w;q.push({dist[v], v});}}}if(dist[t] < INF) printf("%d\n", dist[t]);else puts("-1");
} 
int main() {int n, m, k;cin >> n >> m >> k;while (m--) {int u, v, w;cin >> u >> v >> w;edge[u].push_back({v, w});}while (k--) {int s, t;cin >> s >> t;Djikstra(s, t);}return 0;
}

租房

因为是无向图, 所以st的最短距离就是ts的最短距离

  • 正向思维
    • 对每个点跑Djikstra,求得到那三个点的最短距离, 然后取最小值
  • 逆向思维
    • 从其余点到那三个点的最短距离就等于那三个点到其余点的最短距离
    • 对那三个点各跑一次Djikstra, 求得三个点到其余个点的最短距离
    • 再遍历各点, 算出各点到那三个点的最短距离之和, 取min
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 5e3+5;
const int INF = 0x3f3f3f3f;
int n, m, a, b, c;
vector<PII> edges[N];
int dist[N];
int f[3][N];
bool distOver[N];
void djikstra(int k, int s) {memset(dist, 0x3f, sizeof(dist));memset(distOver, false, sizeof(distOver));dist[s] = 0;priority_queue<PII, vector<PII>, greater<PII>> q;q.push({dist[s], s});while (!q.empty()) {int u = q.top().second;q.pop();if (distOver[u]) continue;distOver[u] = true;for (auto [v, w] : edges[u]) {if (dist[u] + w < dist[v]) {dist[v] = dist[u] + w;q.push({dist[v], v});}}}    memcpy(f[k], dist, sizeof(dist));
}
int main() {cin >> n >> m;while (m--) {int u, v, w;cin >> u >> v >> w;edges[u].push_back({v, w});edges[v].push_back({u, w});}cin >> a >> b >> c;djikstra(0, a);djikstra(1, b);djikstra(2, c);    int ans = INF;// 3行n列, 按列求和, 求列和的最小值, // 对应列序号的点即为到3个点的最近点// 列和即为到3个点的最短距离之和for (int i = 1; i <= n; i++) {int temp = f[0][i] + f[1][i] + f[2][i];ans = min(ans, temp);}cout << ans << endl;return 0;
}

聚会


所有同学周末要到小蜗家聚会,聚会结束后同学们都会回家。为了合理安排时间,小蜗想要知道对于在路上来回花费时间最长的同学,他在路上要花费多少时间。

题目说的是来回花费时间最大的点

s点到其它点的距离很好求, 直接在s点处跑djistra即可获得到其余点的最短距离

但由于是有向图, 其余点到s点的最短距离并不等于s点到其余点的最短距离

如何求其余n-1个点到s点的最短距离?

暴力想法: 枚举其余n-1个点, 对每个点跑一次djistra, 求出n-1个点到目标点的最短距离, 求他们的最大值, 显然时间复杂度为: O ( n m l o g m ) O(nmlogm) O(nmlogm)

优化: 其余n-1个点到s的距离等于在反图中, s点到其余点的最短距离

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5+5;
const int INF = 0x3f3f3f3f;
int n, m, k;
vector<PII> edges[2][N];
int dist[N];
int f[2][N];
bool distOver[N];
void djikstra(int k, int s) {memset(dist, 0x3f, sizeof(dist));memset(distOver, false, sizeof(distOver));dist[s] = 0;priority_queue<PII, vector<PII>, greater<PII>> q;q.push({dist[s], s});while (!q.empty()) {int u = q.top().second;q.pop();if (distOver[u]) continue;distOver[u] = true;for (auto [v, w] : edges[k][u]) {if (dist[u] + w < dist[v]) {dist[v] = dist[u] + w;q.push({dist[v], v});}}}    memcpy(f[k], dist, sizeof(dist));
}
int main() {cin >> n >> m >> k;while (m--) {int u, v, w;cin >> u >> v >> w;edges[0][u].push_back({v, w});edges[1][v].push_back({u, w});}djikstra(0, k);djikstra(1, k);int ans = 0;for (int i = 1; i <= n; i++) {int temp = f[0][i] + f[1][i];ans = max(ans, temp);}cout << ans << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/144853.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

相亲交友系统 现代爱情的导航仪

在这个数字化的时代&#xff0c;人们的生活方式发生了翻天覆地的变化&#xff0c;其中最显著的变化之一便是交友方式的转变。编辑h17711347205随着社会节奏的加快&#xff0c;越来越多的人选择通过相亲交友系统来寻找人生伴侣。相亲交友系统不仅简化了传统的交友流程&#xff0…

【版本更新】TDuckX表单1.9版来了

hi&#xff0c;朋友们大家好&#xff0c;填鸭表单TDuckX迎来了9月的版本更新&#xff1b;接下来让我们看看本次更新的详细内容吧。 1.新增360评估(Bate版本) 360度评估反馈&#xff08;360Feedback&#xff09;&#xff0c;又称“360度考核法”或“全方位考核法”&#xff0c…

人工智能在肿瘤浸润淋巴细胞研究中的最新进展|文献速递·24-09-20

小罗碎碎念 文献速递&#xff5c;目录 一、胆道癌治疗应答的新型AI生物标志物&#xff1a;肿瘤浸润性淋巴细胞的空间分布 补充文献&#xff1a;22年发表于JCO的一篇类似文献 二、生物标志物在肝细胞癌管理中的作用&#xff1a;从发现到临床应用 三、肿瘤样本中免疫细胞浸润水…

pdb文件查看工具pdbripper.exe

下载地址:https://www.bing.com/ck/a?!&&p249322afbfbc575bJmltdHM9MTcyMTM0NzIwMCZpZ3VpZD0yMjBkODE2MC1hYjNhLTZkYTMtMGVlYi05NWQ5YWE3OTZjOGEmaW5zaWQ9NTE4Mg&ptn3&ver2&hsh3&fclid220d8160-ab3a-6da3-0eeb-95d9aa796c8a&psqpdbripper.exe&…

[Linux]:信号(上)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;Linux学习 贝蒂的主页&#xff1a;Betty’s blog 1. 信号的引入 1.1 信号的概念 在Linux系统中&#xff0c;信号&#xff08;…

2024年及未来:构筑防御通胀的堡垒,保护您的投资

随着全球经济的波动和不确定性&#xff0c;通货膨胀已成为投资者不得不面对的现实问题。通胀会侵蚀货币的购买力&#xff0c;从而影响投资的实际回报。因此&#xff0c;制定有效的策略来保护投资免受通胀影响&#xff0c;对于确保资产的长期增值至关重要。在2024年及未来&#…

着色器ShaderMask

说明 实现一个渐变进度条&#xff0c;要求&#xff1a; 颜色渐变的过程是循序渐进的&#xff0c;而不是看起来像是将渐变条逐渐拉长了。 效果 源码 // 渐变进度条Stack(children: [// 背景色板Container(width: 300,height: 8,decoration: BoxDecoration(borderRadius: Bord…

Vue2中路由的介绍和使用

一.路由的基本概念 一说路由&#xff0c;大家首先想到的可能是路由器&#xff0c;路由器的原理就是给连接的设备一个IP地址&#xff0c;通过IP地址来映射到设备&#xff0c;实现连接&#xff0c;本质上是一种映射关系。 在vue2中就是路径与组件间的映射。 路由是使用vue2制作…

基于SpringBoot+Vue的“课件通”中小学教学课件共享平台

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

昇腾大模型推理解决方案MindIE部署

MindIE大模型推理套件 MindIE&#xff08;Mind Inference Engine&#xff0c;昇腾推理引擎&#xff09;是华为公司针对AI全场景推出的整体解决方案&#xff0c;包含丰富的推理加速套件。通过开放各层次AI能力&#xff0c;支撑客户多样化的AI业务需求&#xff0c;使能百模千态&a…

4G 网络下资源加载失败?一次运营商封禁 IP 的案例分享

在工作中&#xff0c;网络问题是不可避免的挑战之一。最近&#xff0c;我们在项目中遇到了一起网络资源加载异常的问题&#xff1a;某同事在使用 4G 网络连接公司 VPN 时&#xff0c;云服务的前端资源居然无法加载&#xff01;通过一系列的排查和分析&#xff0c;我们发现问题的…

数字产业中心:技术赋能产业,如何重塑行业格局!

在数字化浪潮的推动下&#xff0c;数字产业中心正逐步成为推动经济转型升级的重要引擎。这里&#xff0c;技术不仅仅是工具&#xff0c;更是重塑行业格局、引领未来发展的核心力量。 一、技术融合创新&#xff0c;打破传统边界 数字产业中心通过云计算、大数据、人工智能等前沿…

冬瓜排骨汤的做法

1、准备食材‌&#xff1a; 排骨&#xff1a;选择新鲜的排骨&#xff0c;最好使用肋排&#xff0c;因为肋排肉多&#xff0c;适合炖汤。 冬瓜&#xff1a;去皮去瓤&#xff0c;切成适当大小的块状。 姜片、葱段&#xff1a;用于去腥增香。 调味料&#xff1a;盐、胡椒粉、鸡精…

Simapps新版上线:诚邀广大用户体验,参与有奖调查问卷

Hi~朋友&#xff0c;在使用仿真软件时&#xff0c;是否有过以下困扰呢&#xff1f; Simapps是云道智造匠心打造的互联网时代的科学计算中心、基于云的仿真APP商店&#xff0c;承载海量面向场景和模型的仿真APP&#xff0c;为广大中小企业、高校及科研院所提供普惠仿真工具。 Si…

java框架

Oozie任务调度框架 Hue hadoop的WEB工具 seatunnel 数据同步框架 TIDB 大数据库支持事物 StreamX fink和spark的集成 OceanBase 阿里巴巴数据库 dooringx-lib、AntV 可视化H5工具 lowcode、Appsmith&#xff08;推荐&#xff09;、nocoBase 、Budibase、taskbuilder 低代…

创客匠人案例故事|闭关 20 天,私域大爆发,高额发售秘诀是什么?

不是你的能力决定了你的命运&#xff0c;而是你的决定改变了你的人生 王龙老师心赏教养法创始人心赏家园家庭“心生态”发起人国家二级心理咨询师 他是一名致力于解决家庭困境的老师&#xff0c;通过心赏转化五步法&#xff0c;帮助身陷家庭困境的父母&#xff0c;解决自我关系…

故障:ad18导入板框图后无法按外形生成板框

选择设计-板子形状-按照选择对象定义后 无法顺利生产板框&#xff0c;而是如下提示&#xff1a; could not board outline using primitives centerline due to the following errors: multiple paths found from location:(xxxmm,xxxmm) would you like to try finding bo…

Linux入门学习:Linux调试器gdb使用

1. 背景 程序的发布方式有两种&#xff0c;debug模式和release模式&#xff0c;debug是添加调试信息&#xff0c;release是取消调试信息&#xff0c; Linux gcc/g出来的二进制程序&#xff0c;默认是release模式&#xff0c;要使用gdb调试&#xff0c;必须在源代码生成二进制程…

展会上想要留住俄罗斯客户,柯桥成人俄语培训

展品 экспонат 模型 макет 证明(书) свидетельство 预算 бюджет 确认订单 подтверждение заказа 缺点,毛病,缺陷 недостаток 退换 возвращать 更换 заменять 调整 урегулир…

2024好评的开放式耳机排行榜10强?四款开放式蓝牙耳机推荐

在2024年的耳机市场上&#xff0c;有不少的开放式耳机因其高性价比和多功能性而受到关注。这些耳机不仅音质出色&#xff0c;而且舒适度也很高&#xff0c;能够适应多种使用场景&#xff0c;无论是日常通勤、跑步运动还是在家办公&#xff0c;都很能满足使用者的需求。 虹觅 Fi…