Full Tank

题目大意

给定一张 \(n\) 个点,\(m\) 条边的连通无向图,在每个点有一个加油站,油价为该点的点权,每条边的油耗为该边的边权。现给出若干询问,问一辆油箱容量为 \(c\) 的车子是否能从 \(s\) 开到 \(e\),如果可以,求出最小所需的钱。

思路分析

看到这种有图有权求最小消耗的题,我们首先考虑最短路。

第一步,观察数据范围。

我们发现 \(c\) 较小,\(n\) 也不算大,这启示我们可以设计一个由剩余油量和点构成的二维状态,又因为存在多组询问,我们无法接受时间复杂度为 \(O(nmT)\) 的 SPFA,所以考虑用 Dijkstra。

第二步,考虑状态转移。

在跑正常的最短路时,对于每一个已经更新完毕的点,我们都借助它来更新其他点,但在这题中,我们设计了二维的状态,在每一个点都有两种操作:扣油去往其他的点或是原地不动花钱加油,我们需要同时考虑这两种操作。

具体的说,对于每一个二维的点 \((x,m)\)(\(x\) 表示当前位置,\(m\) 表示当前油量),我们可以用这个点更新点 \((x,m+1)(m+1\le c)\) 和所有的 \((y,m-w_{xy})(y\in \text{to}_x)\),更新方法类似于 Dijkstra。

然后就可以轻松写出代码了!

代码

#include <bits/stdc++.h>
using namespace std;
const int N=2010,M=20020,C=105;//点数,边数,最大油箱容量 int to[M],nxt[M],head[N],w[M],p[N];//图,边权,点权
int idx,n,m,c,s,e,in1,in2,in3,ans,Q;
int vis[N][C],dis[N][C];//二维的点,vis表示是否访问,dis是距离 struct node{int x,cost,you;}now;
bool operator < (node a,node b){return a.cost>b.cost;}//在优先队列中按所花的钱排序
priority_queue <node> q; void add(int u,int v,int c){idx++;to[idx]=v;w[idx]=c;nxt[idx]=head[u];head[u]=idx;} int bfs(int s){
while(!q.empty()) q.pop();//一定要清空!!!
memset(vis,0,sizeof vis);//初始化
memset(dis,0x3f,sizeof dis);
q.push(node{s,0,0});
dis[s][0]=0;
while(!q.empty()){
now=q.top();q.pop();
if(now.x==e) return now.cost;//到达终点
if(vis[now.x][now.you]) continue;
vis[now.x][now.you]=1;
if(now.you<c) //如果当前油箱没有满
if(dis[now.x][now.you+1]>now.cost+p[now.x]){
dis[now.x][now.you+1]=now.cost+p[now.x];//更新状态
q.push(node{now.x,now.cost+p[now.x],now.you+1});//加油,入队
}
for(int i=head[now.x];i;i=nxt[i]){
if(now.you<w[i]) continue;//无法通过
if(dis[to[i]][now.you-w[i]]>now.cost){//可以通过,更新状态
dis[to[i]][now.you-w[i]]=now.cost;
q.push(node{to[i],now.cost,now.you-w[i]});//扣油,入队
}
}
}
return -1;
} int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&p[i]);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&in1,&in2,&in3);
in1++;in2++;//点从0到n-1,我们统一加1
add(in1,in2,in3);add(in2,in1,in3);
}
scanf("%d",&Q);
while(Q--){
scanf("%d%d%d",&c,&s,&e);
s++;e++;
ans=bfs(s);
if(ans==-1) puts("impossible");//无解
else printf("%d\n",ans);
}
return 0;
}

Full Tank 题解的更多相关文章

  1. [题解](优先队列广搜)POJ_3635_Full Tank

    用二元组$(city,fuel)$即可记录所有状态,以当前花费为关键字优先队列,开数组记录直接做即可 有一个点在于每次不用枚举所有的加油数量,只需要加一即可,因为如果在加一升更优的话又会扩展出加更多油 ...

  2. POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]

    题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...

  3. POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]

    题目链接:http://poj.org/problem?id=3635 Description After going through the receipts from your car trip ...

  4. leetcode & lintcode 题解

    刷题备忘录,for bug-free 招行面试题--求无序数组最长连续序列的长度,这里连续指的是值连续--间隔为1,并不是数值的位置连续 问题: 给出一个未排序的整数数组,找出最长的连续元素序列的长度 ...

  5. hdoj 4445 Crazy Tank 物理题/枚举角度1

    Crazy TankTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  6. [LeetCode 题解]:Gas Station

    前言   [LeetCode 题解]系列传送门:  http://www.cnblogs.com/double-win/category/573499.html   1.题目描述 There are ...

  7. 【题解】APIO2013机器人

    其实这题前前后后的思考时间加起来应该有两天之久了,dp状态,转移方式等等都还是比较好想,然而左看右看觉得spfa复杂度未免太爆炸……然后选择看了一篇题解,发现在多重优化之下,其实是可以过的…… 首先建 ...

  8. UVA11367 Full Tank? 【分层图最短路】

    题目 After going through the receipts from your car trip through Europe this summer, you realised that ...

  9. Codeforces Round #436 (Div. 2) 题解864A 864B 864C 864D 864E 864F

    A. Fair Game time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  10. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

随机推荐

  1. Kubernetes(k8s) Web-UI界面(二):部署和访问Kuboard

    目录 一.系统环境 二.前言 三.Kuboard简介 四.部署Kuboard 五.访问kuboard 六.总结 七.附加信息 一.系统环境 本文主要基于Kubernetes1.21.9和Linux操作 ...

  2. SQL SERVER 查看表说明,字段属性

    查询表字段属性,说明等: 1 SELECT 2 表名=case when a.colorder=1 then d.name else '' end, 3 表说明=case when a.colorde ...

  3. 暗黑2能用Java开发?还能生成APP?

    最近烧哥发现个宝藏项目,竟然用Java开发了暗黑2出来. 众所周知,暗黑2是暴雪开发的一款经典游戏,距今虽有20多年,仍然有很多粉丝. 粉丝延续热情的方式有很多,一种是做Mod,比如魔电,对怪物.技能 ...

  4. 初识常量变量、字符串、ASCII编码表、转义字符表

    一.常量.变量 1.枚举常量(enum) 枚举常量不能更改,枚举常量所创造出的变量可以更改 正确 错误 2.常变量 3.#define定义的标示变量 二.数组 "abc"--'a' ...

  5. JDBC的增删改-结果集的元数据-Class反射-JDBC查询封装

    一.使用JDBC批量添加 ​ 知识点复习: ​1.JDBC的六大步骤 (导入jar包, 加载驱动类,获取连接对象, 获取sql执行器.执行sql与并返回结果, 关闭数据库连接) 2.​封装了一个DBU ...

  6. 关于 async 和 await 两个关键字(C#)【并发编程系列】

    〇.前言 对于 async 和 await 两个关键字,对于一线开发人员再熟悉不过了,到处都是它们的身影. 从 C# 5.0 时代引入 async 和 await 关键字,我们使用 async 修饰符 ...

  7. 2023-7-27 WPF自定义命名空间在xaml中的使用

    xaml自定义命名空间 [作者]长生 为啥要用自定义命名空间 这是常见的几种命名空间 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ ...

  8. gulp来处理html、css、js资源啦

    gulp 一般用于处理自动化任务,默认情况无法处理模块化,也不会用于大型项目,但它可以使用各种插件来编译 html.css.js 等资源. 不清楚如何使用 gulp 开启任务的朋友可以参考 gulp使 ...

  9. [oracle]使用impdp导入数据时卡在视图

    前言 oracle 19c使用impdp的时候卡在导入视图的地方一点不动,也没啥提示.根据网上资料,oracle 19在导入视图的时候会有bug. 步骤 查看导入任务 sqlplus / as sys ...

  10. Java内存溢出时,还能正常处理请求吗?

    当你被问到"当Java程序发生内存溢出时,进程还能正常处理请求吗?"这样的面试题,会不会很懵?这里分享一次网友车辙在当初刚毕业那几年,意义风发,总觉得天下没有自己不会的面试题.然后 ...