博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AcWing:176. 装满的油箱(bfs + dijiskla思想)
阅读量:5086 次
发布时间:2019-06-13

本文共 2723 字,大约阅读时间需要 9 分钟。

有N个城市(编号0、1…N-1)和M条道路,构成一张无向图。

在每个城市里边都有一个加油站,不同的加油站的单位油价不一样。

现在你需要回答不超过100个问题,在每个问题中,请计算出一架油箱容量为C的车子,从起点城市S开到终点城市E至少要花多少油钱?

输入格式

第一行包含两个整数N和M。

第二行包含N个整数,代表N个城市的单位油价,第i个数即为第i个城市的油价pipi。

接下来M行,每行包括三个整数u,v,d,表示城市u与城市v之间存在道路,且车子从u到v需要消耗的油量为d。

接下来一行包含一个整数q,代表问题数量。

接下来q行,每行包含三个整数C、S、E,分别表示车子油箱容量、起点城市S、终点城市E。

输出格式

对于每个问题,输出一个整数,表示所需的最少油钱。

如果无法从起点城市开到终点城市,则输出”impossible”。

每个结果占一行。

数据范围

1N10001≤N≤1000,

1M100001≤M≤10000,
1pi1001≤pi≤100,
1d1001≤d≤100,
1C1001≤C≤100

输入样例:

5 510 10 20 12 130 1 90 2 81 2 11 3 112 3 7210 0 320 1 4

输出样例:

170impossible

 

算法:bfs + dijiskla思想

题解:这题是用bfs + 优先队列来做,而且需要用到dijiskla的思想,那么我们可以用枚举法来做,首先从起点出发,先加一升油试一下,加一升油能到达的站点放入队列,因为队列是以花费钱来从小到大排序,所以我在把这个加了一升油的情况放入队列,如果这个加了一升油的情况还是花费最小的话,我就会继续加第二升油,如果不是的话,那么我就会用到其他的。到最后的时候,可能最开始第一个点的加一升油还没有用到,那是因为它并不是最优解,你思考一下,多加一升油的性价比就不高了,你还会去多加n升油吗,所以之后的解就都不是我们要找的最优解,之后就是重复我最开始所说的加一升油试一试这个思路。如果还是不够理解的话,可以看代码,代码上也有解释哟!

 

#include 
#include
#include
#include
#include
using namespace std;const int maxn = 1e4+7;struct node { int u, f, w; friend bool operator < (node a, node b) { //优先队列重载,权值小的排前面 return a.w > b.w; }};vector
> g[maxn];int n, m;int wn[maxn];int dp[maxn][105];int vis[maxn][105];int c, s, e;bool check1(int u, int f) { //判断是否能够在当前站点加一升油 if(f + 1 <= c && !vis[u][f + 1] && dp[u][f + 1] > dp[u][f] + wn[u]) { //如果能加一升油,并且加这升油一定比原来的那个好(原来的那个可能是初始化的INF,也可能是已经经过的这个地方时更新的值) return true; } return false;}bool check2(int f, int v, int p, int w) { //判断下一个站点是否能走 if(f >= p && !vis[v][f - p] && dp[v][f - p] > w) { //如果当前油要大于需要花费的油,并且原来的费用比现在的要高(同理,可能是INF,也可能是更新过的值) return true; } return false;}int bfs() { priority_queue
q; memset(vis, 0, sizeof vis); memset(dp, 0x3f3f3f3f, sizeof dp); dp[s][0] = 0; q.push((node){s, 0, 0}); while(!q.empty()) { node now = q.top(); q.pop(); int u = now.u; int f = now.f; int w = now.w; vis[u][f] = 1; if(u == e) { return w; } if(check1(u, f)) { //先加一升油试一下 dp[u][f + 1] = dp[u][f] + wn[u]; q.push((node){u, f + 1, dp[u][f + 1]}); } int len = g[u].size(); for(int i = 0; i < len; i++) { int v = g[u][i].first; int p = g[u][i].second; if(check2(f, v, p, w)) { dp[v][f - p] = w; q.push((node){v, f - p, w}); } } } return -1; //无解}int main() { scanf("%d %d", &n, &m); for(int i = 0; i < n; i++) { scanf("%d", &wn[i]); } for(int i = 1; i <= m; i++) { int u, v, w; scanf("%d %d %d", &u, &v, &w); g[u].push_back(make_pair(v, w)); g[v].push_back(make_pair(u, w)); } int q; scanf("%d", &q); while(q--) { scanf("%d %d %d", &c, &s, &e); int ans = bfs(); if(ans == -1) { printf("impossible\n"); } else { printf("%d\n", ans); } } return 0;}

 

转载于:https://www.cnblogs.com/buhuiflydepig/p/11367487.html

你可能感兴趣的文章
JVM内存管理&GC
查看>>
八皇后问题
查看>>
mysql中find_in_set()函数的使用
查看>>
Golang 实现守护进程实例
查看>>
java学习笔记---循环与选择语句
查看>>
Android 建立Menu选单&&onOptionsItemSelected (转)
查看>>
[编写高质量代码:改善java程序的151个建议]建议106 动态代理
查看>>
Spring核心项目及微服务架构方向
查看>>
my new 高精度模板【高精度】
查看>>
c#编程指南(三) 泛型委托(Generic Delegate)
查看>>
tomcat - 认识
查看>>
无线点餐系统应用源码(转)
查看>>
蜕变测试概述及典型案例
查看>>
$如何用Python装饰器实现一个代码计时器?
查看>>
vue指令详解
查看>>
Struts2学习之路(三)—— Action方法调用
查看>>
滑动效果的原理及实践一个滑动小插件
查看>>
git learn.
查看>>
mvn创建web项目
查看>>
(转)php_curl模拟登录有验证码实例
查看>>