In Touch HDU - 5361(优先队列优化dijkstra+并查集优化)

[最短路]使用优先队列优化的Dijkstra算法 用邻接矩阵的Dijkstra算法的代码:int cost[RANGE][RANGE]; int d[RANGE]; bool used[RANGE]; int n,m; //顶点数,边数 void Dijkstra( int s ) { int i,v,u; for( i=1; i<=n; ++i ) { 阅读详情

In Touch

HDU - 5361

There are n soda living in a straight line. soda are numbered by 1,2,…,n from left to right. The distance between two adjacent soda is 1 meter. Every soda has a teleporter. The teleporter of i-th soda can teleport to the soda whose distance between i-th soda is no less than li and no larger than ri. The cost to use i-th soda's teleporter is ci.

The 1-st soda is their leader and he wants to know the minimum cost needed to reach i-th soda (1≤i≤n)

.
Input There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains an integer n (1≤n≤2×105), the number of soda.
The second line contains n integers l1,l2,…,ln. The third line contains n integers r1,r2,…,rn. The fourth line contains n integers c1,c2,…,cn. (0≤li≤ri≤n,1≤ci≤109)
Output For each case, output n integers where i-th integer denotes the minimum cost needed to reach i-th soda. If 1-st soda cannot reach i-the soda, you should just output -1. Sample Input
1
5
2 0 0 0 1
3 1 1 0 5
1 1 1 1 1
Sample Output
0 2 1 1 -1

        
  
Hint
If you need a larger stack size, 
please use #pragma comment(linker, "/STACK:102400000,102400000") and submit your solution using C++.
        
 

题意:有n个点站成一排,相邻距离为1,每个点 i 可以联系上距离自己 x 的点并且花费Ci,其中Li<=x<=Ri,从点1开始,求联系到每个点的最少费用。

思路:边太多,不可能建完边后再求最短路,感觉有点像隐式图,然后就是巧妙用到Dijstra,需要注意到的就是,这里是每个点有权值而不是边,那么dist[i]表示从1到 i 的花费再加上点 i 的花费,这样每个点就只会被更新一次,更新后在以后就不会再次被更新了,这里用到并查集把已经更新的点得father指向还没被更新的点。

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<ll,int> Pir;
const ll INF = 1LL << 60;
const int maxn = 2*1e5+10;
ll L[maxn],R[maxn],C[maxn],dis[maxn];
int n,pre[maxn];
void init(){
    for(int i = 0; i <= n+5; i++){
        pre[i] = i;
        dis[i] = INF;
    }
}
int Find(int x){
    if(x == pre[x])
        return x;
    else return pre[x] = Find(pre[x]);
}
void solve(){
    dis[1] = C[1];
    priority_queue<Pir,vector<Pir>,greater<Pir> > q;
    q.push(make_pair(dis[1],1));
    while(!q.empty()){
        Pir st = q.top();//相当于选出最小的作为起点
        q.pop();
        int u = st.second;
        for(int i = -1; i <= 1; i += 2){
            int l = u + i * L[u];
            int r = u + i * R[u];
            if(l > r) swap(l,r);
            l = max(1,l);
            l = min(n+1,l);
            if(l > r) continue;//确定合理距离范围
            for(int v = l;;v++){
                v = Find(v);//直接指向未更新的点
                if(v < 0 || v > n || v > r) break;
                if(dis[v] > dis[u] + C[v]){//每次都加上当前点需要的花费。
                    dis[v] = dis[u] + C[v];
                    q.push(make_pair(dis[v],v));
                }
                pre[Find(v)] = Find(v+1);//不过有没有经过更新,这个点不能再更新了只能更新一次,所以这个点的父亲将指向下一个点
            }
        }
    }
    printf("0");
    for(int i = 2; i <= n; i++){
        if(dis[i] >= INF)
            printf(" -1");
        else
            printf(" %lld",dis[i]-C[i]);//因为在计算时到达每一个点时都加上了这个点的花费,而题目要求只有从这个点到达其他点时才会用这个花费,所以每个点都应减去它本身的花费
    }
    puts("");
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i = 1; i <= n; i++){
            scanf("%lld",&L[i]);
        }
        for(int i = 1; i <= n; i++){
            scanf("%lld",&R[i]);
        }
        for(int i = 1; i <= n; i++){
            scanf("%lld",&C[i]);
        }
        init();
        solve();
    }
    return 0;
}


 
这个题解是看的别的博客,道理说的通,但是有点不明白的是如果初始dis【1】 = 0,然后每次算最小花费是队列中取出最小的加起点花费(和题意相符)就不对
望大神指点

错误代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<ll,int> Pir;
const ll INF = 1LL << 60;
const int maxn = 2*1e5+10;
ll L[maxn],R[maxn],C[maxn],dis[maxn];
int n,pre[maxn];
void init(){
    for(int i = 0; i <= n+5; i++){
        pre[i] = i;
        dis[i] = INF;
    }
}
int Find(int x){
    if(x == pre[x])
        return x;
    else return pre[x] = Find(pre[x]);
}
void solve(){
    dis[1] = 0;
    priority_queue<Pir,vector<Pir>,greater<Pir> > q;
    q.push(make_pair(dis[1],1));
    while(!q.empty()){
        Pir st = q.top();//相当于选出最小的作为起点
        q.pop();
        int u = st.second;
        for(int i = -1; i <= 1; i += 2){
            int l = u + i * L[u];
            int r = u + i * R[u];
            if(l > r) swap(l,r);
            l = max(1,l);
            l = min(n+1,l);
            if(l > r) continue;//确定合理距离范围
            for(int v = l;;v++){
                v = Find(v);//直接指向未更新的点
                if(v < 0 || v > n || v > r) break;
                if(dis[v] > dis[u] + C[u]){//为什么是dis[v] > dis[u] + c[u]呢因为题目说从那个点出发需要使用转换器使用转换器要花费cost所以花费的是起点的cost
                    dis[v] = dis[u] + C[u];
                    q.push(make_pair(dis[v],v));
                }
                pre[Find(v)] = Find(v+1);//不过有没有经过更新,这个点不能再更新了只能更新一次,所以这个点的父亲将指向下一个点
            }
        }
    }
    printf("0");
    for(int i = 2; i <= n; i++){
        if(dis[i] >= INF)
            printf(" -1");
        else
            printf(" %lld",dis[i]);
    }
    puts("");
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i = 1; i <= n; i++){
            scanf("%lld",&L[i]);
        }
        for(int i = 1; i <= n; i++){
            scanf("%lld",&R[i]);
        }
        for(int i = 1; i <= n; i++){
            scanf("%lld",&C[i]);
        }
        init();
        solve();
    }
    return 0;
}

Dijkstra最短路径算法优先队列优化版 模板参考kuangbin 数据结构方面: const int INF=0x3f3f3f3f; const int maxn=1000010; struct qnode { int v; int c; qnode(int _v=0,int _c=0):v(_v),c(_c){} bool operator &lt;(const qnode &amp;r)cons... 阅读详情

相关推荐

自偏置电流镜设计实例

自偏置电流镜设计实例 一、概述 ​ 众所周知,电流镜属于模拟电路设计中的一个基本模块,可为其他模块提供偏置电流,例如在放大器中提供偏置电流以形成尾电流源并确定直流偏置点。本文将会介绍一种自偏置的电流镜,从原理出发,并以0.18um的工艺进行设计和仿真。 二、原理 ​ 如图一所示的电路,也称之为Beta-multiply reference电路,其中M2的尺寸是M1的k倍。M3复制M4的电流,M2和M1的漏极电流相同,但是VGS并不相等。其中 VGS=2IμnCoxW/...

aonuanjiang的博客 1万+

bzoj 1576: [Usaco2009 Jan]安全路经Travel(dijkstra堆优化+并查集)

1576: [Usaco2009 Jan]安全路经Travel Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 968  Solved: 330 [Submit][Status][Discuss] Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i

clover_hxy的博客 658

[V-10]ARMv8/v9-CPU Virtualization-CPU虚拟化架构简介(vCPU/vPE)

本文简要介绍了CPU虚拟化架构的基础知识。

基层架构师的分享 1267

最短路——Dijkstra+优先队列

传送门HDU2544描述 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? 输入输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),...

umalaka的博客 700

M6 Mac mini涨价2500值不值?深度拆解硬件成本与购买决策

统一内存架构将CPU、GPU和内存封装在一起,通过共享高带宽内存池提升数据交换效率,尤其适合本地AI推理和视频渲染等场景。在苹果生态中,起步内存和存储的配置直接决定设备生命周期,因为后期无法自行升级。M6 Mac mini将起步内存从16GB提升至24GB、存储从256GB提升至512GB,同时芯片制程和GPU核心数均有升级,持续负载性能保持率明显改善。对于开发者、内容创作者和本地大模型推理用户,这些变化能转化为实际效率收益;而轻度办公用户则可能面临性能冗余。理解硬件成本结构与自身工作流需求,才能判断这25

weixin_30846347的博客 264

瑞芯微RK3588开发板VSCode远程开发全攻略:从SSH配置到插件优化

本文详细介绍了如何在瑞芯微RK3588开发板上配置VSCode远程开发环境。从Ubuntu系统下的SSH服务设置、VSCode Remote-SSH扩展安装,到连接建立、基础工具链部署,再到针对ARM平台的性能优化与调试配置,提供了一套完整的实战指南,帮助开发者高效利用本地资源进行嵌入式开发。

weixin_28831341的博客 621

In Touch HDU- 5361(最短路+并查集)

There are n soda living in a straight line. soda are numbered by 1,2,…,n from left to right. The distance between two adjacent soda is 1 meter. Every soda has a teleporter. The teleporter of i-th soda...

Coldfresh的博客 480

SPARTAN6 + Verilog - FPGA step by step 从0开始学习(1)

SPARTAN6 + Verilog - FPGA step by step 从0开始学习(1)Step 1 软件安装Step 2 硬件获取Step 3 开始从头到脚建一个工程Step 3.1 新建一个工程 从0开始学习FPGA,最好的办法就是先建一个最简单的模块,并且跑起来,然后再慢慢展开。下面这个例子是要按照一定的周期点亮核心板上的一个led。 Step 1 软件安装 这个从0开始学习是用的xilinx的SPARTAN6。SPARTAN6集成开发环境用ISE,不能用Vivado,各自对应的版本不同。安装

xfacexx点点记录 5508

(迪杰斯特拉)Dijkstra算法 与 普里姆算法(Prim算法)

怎么硕呢 这俩肯定是一个人抄了另一个人的代码。就在花费那一部分 一个是d[u] = mp[u][v]+d[v] (迪杰斯特拉) 另一个是d[u] = mp[u][v] 大体思路就是一直找和以之节点相通的节点之间最省钱的路径就完了。 相比较克鲁斯卡尔来说,一个是以点展开验证边。而克鲁斯卡尔是以边为展开看连接点点是否属于都一个跟(并查集) #include<stdio.h> #include<string.h> #define INF 0x3f3f3f3f //测试样例 /..

朱发财的博客 1956

HDMI2.1 FRL流控 概览

HDMI 2.1 FRL的流控本质是。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 2080

UNet改进(24):注意力机制-从基础原理到高级融合策略

本文系统探讨了如何通过引入各类注意力机制增强UNet在医学图像分割中的性能。文章分为基础篇、进阶篇和高级篇三个层级:基础篇介绍了时序注意力、可变形注意力、分层注意力等8种基础机制;进阶篇提出了5种混合注意力设计;高级篇则探讨了全局+局部+多尺度等复杂组合机制。实验表明,这些注意力模块在心脏MRI、肺部感染等任务中能提升2-15%的分割精度。文章还提供了硬件适配建议和完整实现代码,为研究者提供了全面的技术参考。未来方向包括NAS优化、量子注意力等前沿探索,为UNet在医疗影像等领域的应用革新提供了理论指导。

2501_91516851的博客 763

HDU 5361 In Touch (优先队列+并查集优化)

题意:求源点到所有点的最短距离。每个点只能到达与它相距l到r之间的点,且这个点到达这些点的花费都为c。 思路:这道题和普通最短路的区别是这个图有可能是个极为稠密的图,那么对于dijkstra算法来说时间复杂度太高, 注意到这题有一点特殊之处,每一点连出去的边的边权是相同的,也就是说一个点与源点之间的最短路只会更新一次,也就是说之后我们就可以不考虑更新这个点的最短路了,所以我们可以考虑用

GODSPEED 609

三步实现Java分布式追踪:像“开灯”一样简单

摘要: 本文通过三步实现Java分布式追踪: 引入依赖:配置Spring Cloud Sleuth+Zipkin,自动埋点无需代码侵入; 启动服务:REST接口自动生成Trace/Span ID,日志可验证; 可视化分析:通过Zipkin UI查看调用链耗时和拓扑关系。 亮点:AOP自动埋点、零业务代码修改、支持多服务链路追踪,助力快速定位性能瓶颈。适用于微服务诊断,生产环境可调整采样率平衡性能。(150字)

墨夶的博客 2710

[HDU5361]In Touch

没想到还有这种骚操作,长见识了。

七代目鸽影 230

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

线段树优化连边,Dijkstra(In Touch,HDU 5361)

第二次被vector卡空间。。。但凡用到了vector,空间复杂度就别想算对了。。。以后少用vector,多用链式前向星。(特别是空间比较紧的时候) 还有一些实现上的失误, a=max(1,i-R[i]); b=max(1,i-L[i]); 改成 a=i-R[i]; b=i-L[i]; 就对了,因为前面的代码会导致不一样的结果。 对于这种问题,我只能说对于那些比

xl2015190026的博客 591

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Hdu 5361 In Touch (dijkatrs+优先队列)

题目链接:   Hdu 5361 In Touch 题目描述:   有n个传送机排成一排,编号从1到n,每个传送机都可以把自己位置的东西传送到距离自己[l, r]距离的位置,并且花费c,问从1号传送机到其他传送机的最小花费是多少?? 解题思路:   看了题解发现是dijkstra(求最短单源路径)+并查集(优化),刚开始的时候并不知道怎么用并查集优化,然后就提交了一个没有并查集的代码,...

weixin_30336061的博客 152

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

In Touch (hdu 5361 优先队列的Dij + 并查集优化)

题意:有n个点站成一排,相邻距离为1,每个点 i 可以联系上距离自己 x 的点并且花费Ci,其中Li<=x<=Ri,从点1开始,求联系到每个点的最少费用。 思路:边太多,不可能建完边后再求最短路,感觉有点像隐式图,然后就是巧妙用到Dijstra,需要注意到的就是,这里是每个点有权值而不是边,那么dist[i]表示从1到 i 的花费再加上点 i 的花费,这样每个点就只会被更新一次,更新后在以后就不会再次被更新了,这里用到并查集把已经更新的点得father指向还没被更新的点。

@you! 1032

hdu 5361 2015多校联赛第六场 In Touch

题意:    每个点可以到左右两个范围内的点并花费为Ci, 问1 到 所有点的最短距离。    用普通的优先队列最短路不行,复杂度高,且边较多。 、 这里要用dijstra的一个性质,那就是在未使用过的点中挑选出离S最近的 X,之后这个X不会再更新,如果用优先队列来写的话就表现为从队列里出来的点不会再被更新 我们设到达V点最近的距离为dis[v],        如果我们把

theflowerofac^MQLYES的专栏 484

HDU5361 In Touch(最短路 + 线段树)

/** 题意:一条n个点,第i个点可以到达[i - Ri, i - Li], [i + Li, i + Ri]的任意一个点,花费为Ci,问第1个点 到其他各点的最小花费 思路:Dijkstra + 线段树维护,遇到要更新的data值的时候, 如果data大于等于线段树该节点的最大值,则不更新, 如果小于该节点的最小值,则这个区间的每个点更新,然后放进优先队列,线段树维护的是1到区间[l, r]最...

hnust_Derker的博客 447

hdu5361(2015多校6)--In Touch(变形的dijkstra)

题目链接:点击打开链接 题目大意:给出一个n个数的序列,标号为1到n,对于第i个数,它可以移动到距离i为[ li,ri ]的位置,花费为c[i],输入三行,第一行l[i],第二行r[i],第三行c[i],现在问对于第一个数来说,它移动到第i个位置的最小花费。(1 这是一个每个点可以移动到一段中任意一个点,并且花费一样,这样就不适用与已有的四种最短路,但是可以对dijkstra进行变形,dij是

随风的专栏 820

HDU5361In Touch (最短路+并查集)

题目描述:   有n个传送机排成一排,编号从1到n,每个传送机都可以把自己位置的东西传送到距离自己[l, r]距离的位置,并且花费c,问从1号传送机到其他传送机的最小花费是多少 思路:  从第一个点开始更新, 更新过的点从未被更新的点中除去, 因为在Dijkstra里 每次取出的都是最小的distance, 所以更新过的点 后面肯定不需要再次更新。更新一个点后加入堆中

Rain 563

HDU 5360 - In Touch(最短路)

题目: http://acm.hdu.edu.cn/showproblem.php?pid=5361 题意: 给出n个点可以到达的点的距离差范围(l,r),和每个点的点值。n个点的位置分别为(0,1,2,3...n). 从0点出发,求出到达其他各点的最小花费,如果无法达到则输出“-1”。 思路: dijkstra的思路,在每个点只可能标记一次最短路,所以使用一个set去记录所有点,

Halo 784

hdu 5361 In Touch 题目特点+优先队列的dijikstra 2015 Multi-University Training Contest 6

In Touch Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1208    Accepted Submission(s): 324 Problem Description There are n soda

便纵有千种风情 445

算法-并查集/堆/Dijkstra迪杰斯特拉-水位上升的泳池中游泳

算法-并查集/堆/Dijkstra迪杰斯特拉-水位上升的泳池中游泳 1 题目概述 1.1 题目出处 https://leetcode-cn.com/problems/swim-in-rising-water/ 1.2 题目描述 2 并查集 2.1 思路 注意,平台数字是连续的,且从0到nn-1。则可利用这一特点,从高度1的节点开始,不断和周边比他高度小的节点进行并查集合并。每次遍历后,判断0和nn-1所属并查集是否为同一个祖先,如果是代表已经符合要求,返回遍历的轮数即可(轮数从1开始)。 2.2 代码 c

迷路剑客个人博客 579

[BZOJ1576][Usaco2009 Jan]安全路径Travel(堆优化dijkstra+并查集)

我时常有这样的感觉 在那通往遥远梦想之旅的途中 如果就此止步的话 就会感到输给了自己

zyf2000 1280
上一篇: Prefix Sums CodeForces - 837F(思维+二分+组合数)
下一篇: 叉积
Guuuuuu老师儿
博客等级 码龄9年 259粉丝 718原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值