Description

After going through the receipts from your car trip through Europe this summer, you realised that the gas prices varied between the cities you visited. Maybe you could have saved some money if you were a bit more clever about where you filled your fuel?

To help other tourists (and save money yourself next time), you want to write a program for finding the cheapest way to travel between cities, filling your tank on the way. We assume that all cars use one unit of fuel per unit of distance, and start with an empty gas tank.

Input

The first line of input gives 1 ≤ n ≤ 1000 and 0 ≤ m ≤ 10000, the number of cities and roads. Then follows a line with n integers 1 ≤ pi ≤ 100, where pi is the fuel price in the ith city. Then follow m lines with three integers 0 ≤ u, v < n and 1 ≤ d ≤ 100, telling that there is a road between u and v with length d. Then comes a line with the number 1 ≤ q ≤ 100, giving the number of queries, and q lines with three integers 1 ≤ c ≤ 100, s and e, where c is the fuel capacity of the vehicle, s is the starting city, and e is the goal.

Output

For each query, output the price of the cheapest trip from s to e using a car with the given capacity, or "impossible" if there is no way of getting from s to e with the given car.

Sample Input

5 5
10 10 20 12 13
0 1 9
0 2 8
1 2 1
1 3 11
2 3 7
2
10 0 3
20 1 4

Sample Output

170
impossible 题目大意:n个城市,m条公路构成了一张n个顶点,m条无向边的图。现在要从一个城市驾车到另一个城市,每单位油能走1公里路,已知每个城市的油价(元/单位)和车的油箱容量,问到达目的地的最小花费是多少。
题目分析:以当前的所在城市和油箱剩余油量作为状态参数,最多有 城市数x油箱容量=10^5 个状态,暴力是可以接受的,又让求最小花费,就敲定用广搜了。现在考虑状态转移,当到达一个城市时,无非面临了两种选择:1.当油量足够能通过下条路时,直接扩展;2.加一个单位油(加一个单位油没问题,如果加多的话,会重复,造成不必要的时间浪费)。问题看似已经解决,但如果仅仅是这样的话,会TLE。
  解决办法就是将广搜的过程记忆化,当达到某个状态时解比已经得到的解更优时,搜索才继续进行下去,并更新最优解。要开辟新的数组来记录状态的最优解。 代码如下:
 # include<iostream>
# include<cstdio>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;
const int INF=<<;
struct node
{
int pos,tank,m;
bool operator < (const node &a) const {
return m>a.m;
}
};
struct edge
{
int to,w,nxt;
};
edge e[];
int n,vis[][],dp[][],head[],price[],cnt;
void add(int u,int v,int w)
{
e[cnt].to=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt++;
}
void bfs(int v,int s,int t)
{
priority_queue<node>q;
for(int i=;i<=n;++i)
for(int j=;j<=v;++j)
dp[i][j]=INF;
memset(vis,,sizeof(vis));
dp[s][]=;
node sta;
sta.m=,sta.pos=s,sta.tank=;
q.push(sta);
while(!q.empty()){
node u=q.top();
q.pop();
int pos=u.pos;
vis[pos][u.tank]=;
if(pos==t){
printf("%d\n",u.m);
return ;
}
for(int i=head[pos];i!=-;i=e[i].nxt){
if(u.tank>=e[i].w&&!vis[e[i].to][u.tank-e[i].w]&&dp[e[i].to][u.tank-e[i].w]>u.m){
dp[e[i].to][u.tank-e[i].w]=u.m;
node nxt;
nxt.pos=e[i].to,nxt.tank=u.tank-e[i].w,nxt.m=u.m;
q.push(nxt);
}
}
if(u.tank+<=v&&!vis[pos][u.tank+]&&dp[pos][u.tank+]>dp[pos][u.tank]+price[pos]){
dp[pos][u.tank+]=dp[pos][u.tank]+price[pos];
node nxt;
nxt.pos=pos,nxt.m=dp[pos][u.tank+],nxt.tank=u.tank+;
q.push(nxt);
}
}
printf("impossible\n");
}
int main()
{
int m,q,a,b,c;
while(scanf("%d%d",&n,&m)!=EOF)
{
cnt=;
for(int i=;i<n;++i)
scanf("%d",price+i);
memset(head,-,sizeof(head));
while(m--){
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
scanf("%d",&q);
while(q--){
scanf("%d%d%d",&c,&a,&b);
bfs(c,a,b);
}
}
return ;
}

POJ-3635 Full Tank? (记忆化广搜)的更多相关文章

  1. poj 3249 Test for Job (记忆化深搜)

    http://poj.org/problem?id=3249 Test for Job Time Limit: 5000MS   Memory Limit: 65536K Total Submissi ...

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

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

  3. POJ 1088 滑雪(记忆化搜索)

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 92384   Accepted: 34948 Description ...

  4. POJ 1088 滑雪【记忆化搜索】

    题意:给出一个二维矩阵,要求从其中的一点出发,并且当前点的值总是比下一点的值大,求最长路径 记忆化搜索,首先将d数组初始化为0,该点能够到达的路径长度保存在d数组中,同时把因为路径是非负的,所以如果已 ...

  5. POJ 3635 Full Tank? 【分层图/最短路dp】

    任意门:http://poj.org/problem?id=3635 Full Tank? Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  6. POJ 1088 滑雪 DFS 记忆化搜索

    http://poj.org/problem?id=1088 校运会放假继续来水一发^ ^ 不过又要各种复习,功课拉下了许多 QAQ. 还有呀,就是昨天被一个学姐教育了一番,太感谢了,嘻嘻^ ^ 好了 ...

  7. poj 3278 Catch That Cow (广搜,简单)

    题目 以前做过,所以现在觉得很简单,需要剪枝,注意广搜的特性: 另外题目中,当人在牛的前方时,人只能后退. #define _CRT_SECURE_NO_WARNINGS //这是非一般的最短路,所以 ...

  8. poj 1088 滑雪_记忆化搜索

    题意:略 直接用记忆化搜索就行了 #include<cstdio> #include<iostream> using namespace std; int n,m; int m ...

  9. POJ 2738 Two Ends(记忆化)

    Description In the two-player game "Two Ends", an even number of cards is laid out in a ro ...

随机推荐

  1. Executor简析

    本文只做简要解析,实际情形下我们多用spring的taskExecutor 直接使用new Thread()创建线程的缺点: 1.new Thread()耗费性能 2.调用new Thread()创建 ...

  2. 如何修改bootstrap模态框的backdrop蒙版区域的颜色?

    参考地址: http://www.cnblogs.com/9miao/p/4988196.html 蒙板样式实现: 大家或许注意到了,在做模态弹出窗时,底部常常会有一个透明的黑色蒙层效果:在Boots ...

  3. HDU 1796 How many integers can you find(容斥)题解

    思路:二进制解决容斥问题,就和昨天做的差不多.但是这里题目给的因子不是质因子,所以我们求多个因子相乘时要算最小公倍数.题目所给的因数为非负数,故可能有0,如果因子为0就要删除. 代码: #includ ...

  4. Unity3D学习笔记(二十一):InputFiled、Dropdown、Scroll Rect、Mask

    InputFiled组件(输入框) Text Component(显示内容):显示输入内容的Text的组件 Text(输入内容):输入的文本内容 Character Limit:字符数量限值,0是无限 ...

  5. C#学习笔记(十一):类和对象

    面向对象 为什么要面向对象: 1.和函数一样,把算法封装起来,方便复用 2.更好理解自己和别人写的代码 封装:数据.结构.逻辑的封装,方便复用 多态:同一个对象,同一种指令,不同的行为(反应) 继承: ...

  6. C#学习笔记(五):while循环和for循环

    while循环 while循环和for循环,可以相互替换,范围和效能一样,理解事物的逻辑不一样 while循环用于条件不确定的逻辑 for循环用于计算次数的逻辑 for循环 快捷写法,按两下TAB i ...

  7. WebForm、MVC、流式计算

    11月.NET技术讨论会圆满结束,会议纪要及相关文档如下如下:  1.WebForm预编译演示 文档:http://gitlab.light.fang.com/kongguDonet.Demo/Pre ...

  8. CSU 1808 地铁(最短路变形)

    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808 题意: Bobo 居住在大城市 ICPCCamp. ICPCCamp 有 n 个地铁站, ...

  9. MVC ---- 增删改成 EF6

    1.MVC EF6的增删改成小练习 namespace T4Demo { public partial class Form1 : Form { NBEntities nb = new NBEntit ...

  10. 【转】Windows Server 2008 R2怎样设置自动登陆

    Windows Server 2008 R2是一款服务器操作系统,提升了虚拟化.系统管理弹性.网络存取方式,以及信息安全等领域的应用,Windows Server 2008 R2也是第一个只提供64位 ...