codeforces974E(div3)(优先队列实现dijstra算法,devc++的优先队列用greater报错)

news/2024/10/9 22:17:58

解题历程:

看到两边同时移动,计算最终的相遇时间,我就想到两边同时计算各点到起点的最短距离,就是使用dijstra算法,最后所有节点取两次计算的最大值,再对所有节点取最小值,就是最终答案了,可是这个思路没有考虑有马的情况,思考一番后发现可以多列一个数组记录有马的情况下的行走最短路,然后将有马和无马取最小值合并成单源最短路的结果

代码:

#include<bits/stdc++.h>#define ll long long#define inf 1e18
using namespace std;void solve() {int n,m,h;cin>>n>>m>>h;vector<vector<pair<ll,ll>>>a(n+1);vector<int>horse(n+1,0);for(int i=0;i<h;i++){int l;cin>>l;horse[l]=1;}for(int i=1;i<=m;i++){ll u,v,w;cin>>u>>v>>w;a[u].push_back({v,w});a[v].push_back({u,w});}auto dijstra=[&](int s){priority_queue<pair<ll,ll>,vector<pair<ll,ll> >,greater<>>pq;//devc++要用greater<ll>vector<ll>vis(2*n+5,inf);pq.push({0ll,2*s});while(!pq.empty()){ll d=pq.top().first;ll u=pq.top().second;pq.pop();if(vis[u]!=inf)continue;vis[u]=d;int x=u%2;int y=(u+1)/2; if(x==0&&horse[y]){pq.push({d,y*2-1});}for(auto t:a[y]){pq.push({d+t.second/(1+x),2*t.first-x});}}vector<ll>d(n+1,inf);for(int i=1;i<n+1;i++){d[i]=min(vis[i*2],vis[2*i-1]);}return d;};auto dl=dijstra(1);auto dr=dijstra(n);ll ans=inf;for(int i=0;i<n;i++){ans=min(ans,max(dl[i+1],dr[i+1]));}if(ans!=inf)cout<<ans<<endl;elsecout<<-1<<endl;
}int main(void )
{   ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);int test=1;cin>>test;while(test--){solve();}return 0;
}

感悟:

  1. 以后卡题了可以考虑多开数组记录数据,算法竞赛不用省空间

  2. 优先队列的dijstra算法要实现的话只需要一个优先队列,一个数组,优先队列用pair容器,pair用于存储该点的编号和该点到起点的距离,数组起始都是inf,用于记录对应编号的点到起点的最短距离。首先将起点和距离0装入队列。然后循环以下操作:将队首出队,队首是队列中离起点最近的点,判断该点是否已经赋值过,若是没有被赋值过,则将该距离赋给该点,否则就不赋值跳过后面的操作,赋值后将该点相关联的点和父点的离起点的距离加上父点到该点的距离一起存入队列。循环以队列为空时停止,此时数组的数值就是对应点到起点的最短路径了。

  3. dijstra算法的思想和dp非常的像,都是将局部的最优解存起来,在后面的步骤可以直接用,这样可以省去重复的计算

  4. devc++有一个坑点,优先队列中的greater<>中尖括号内需要加上变量类型,比如greater< int >,不然的话会报错,有些编译器不加也能运行

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

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

相关文章

隧道云 cpolar

Dify+Ollama+llava大模型本地搭建个人AI知识库并实现远程访问 https://www.bilibili.com/video/BV1tu24YyEDh/?spm_id_from=333.337.search-card.all.click&vd_source=57e261300f39bf692de396b55bf8c41bcpolar https://www.cpolar.com/features什么是cpolar?cpolar是一种…

C++类

C++类 类 // public 成员提供类的接口,暴漏给外界,供外界使用 // private:提供各种实现类功能的细节方法,但不暴漏给使用者,外界无法使用 // 注意:struct 是成员默认为 public 的 class、class 成员默认是 private class student{ public:int number;char name[100]; …

SE_Paring_Work2

目录具体分工 PSP表格 解题思路描述与设计实现说明3.1 团队作业功能的实现思路 3.2 关键实现的流程图 3.3 重要/有价值的代码片段附加特点设计与展示4.1 设计的创意独到之处及意义 4.2 实现思路 4.3 重要/有价值的代码片段目录说明和使用说明5.1 目录的组织 5.2 如何运行单元测…

PasteForm最佳CRUD实践,实际案例PasteTemplate详解之3000问(四)

无论100个表还是30个表,在使用PasteForm模式的时候,管理端的页面是一样的,大概4个页面, 利用不同操作模式下的不同dto数据模型,通过后端修改对应的dto可以做到控制前端的UI,在没有特别特殊的需求下可以做到快速的实现CRUD! 免去版本兼容问题,免去前后端不一致的问题,免…

中国移动宽带 IPv6 连接到公网,家庭宽带设置服务器(2024年10月)

摘要: 1、中国移动的宽带,已经支持 IPv6,需要宽带光猫上做好设置。 2、需要从 中国移动 的服务器上获取公网 IPv6 地址。操作: 1、确保宽带WAN连接的前缀获取方式:Prefix Delegation 网关的默认登录用户名(user)、密码,在设备的背面有写着。 如果不是,就联系客服,询问…

实验1 现代C++基础编程

任务1: 源代码task1.cpp1 #include <iostream>2 #include <string>3 #include <vector>4 #include <algorithm>5 6 using namespace std;7 8 // 声明9 // 模板函数声明 10 template<typename T> 11 void output(const T &c); 12 13 // 普通…

深度学习实战人脸表情识别【源码+模型+PyQt5界面】

本研究旨在实现一个基于深度学习的人脸表情识别系统,以准确地识别七种常见的人脸表情:惊讶、恐惧、厌恶、开心、悲伤、愤怒和正常。系统流程包括人脸定位和表情识别两个主要步骤。在人脸定位阶段,采用深度学习算法,通过训练一个卷积神经网络(CNN),实现对图像中人脸位置的…

20222303 2024-2025-1 《网络与系统攻防技术》实验一实验报告

1.实验内容 在本周的学习中,重新回顾了栈和堆的概念,还学习了安全漏洞的相关概念,然后聚焦在其中的缓冲区溢出漏洞上,明白了缓冲区溢出的定义及发生的原理,并了解了缓冲区溢出发展历史上的一些经典攻击案例,收获颇丰。 在本次的实验中,我掌握了反汇编与十六进制编程器相…