题意:传送门
题解:考虑每个状态,当前所在城市和所剩余的油量,起始状态为
(
s
,
0
)
(s,0)
(s,0),拓展到新的状态有
(
c
i
t
y
,
f
u
e
l
+
1
)
(city,fuel+1)
(city,fuel+1),表示在该城市再添加一升油,第二种就是油量足够跑到下一个点上,就转化成一个最短路问题了。
c
o
d
e
:
code:
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int N=1e3+5;
const int C=1e2+5;
const int M=2e4+5;
int n,m,u,v,d,q,c,s,e,dist[N][C],price[N];
struct edge{
int u,v,w,next;
};
edge edges[M];
int head[N],tot;
void init()
{
memset(head,-1,sizeof head);
tot=0;
}
void add_edges(int u,int v,int w)
{
edges[tot].u=u;edges[tot].v=v;edges[tot].w=w;edges[tot].next=head[u];head[u]=tot++;
edges[tot].u=v;edges[tot].v=u;edges[tot].w=w;edges[tot].next=head[v];head[v]=tot++;
}
struct state{
int cost,ver,fuel;
state(int _cost=0,int _ver=0,int _fuel=0):cost(_cost),ver(_ver),fuel(_fuel){}
bool operator < (const state &a)const {
return cost>a.cost;
}
};
bool st[N][C];
int dijkstra()
{
memset(dist,0x3f,sizeof dist);
memset(st,false,sizeof st);
dist[s][0]=0;
priority_queue<state>heap;
heap.push(state(0,s,0));
while(!heap.empty()){
state t=heap.top();
heap.pop();
int cost=t.cost,ver=t.ver,fuel=t.fuel;
if(st[ver][fuel]==true)continue;
if(ver==e){
return cost;
}
st[ver][fuel]=true;
if(fuel+1<=c&&dist[ver][fuel+1]>dist[ver][fuel]+price[ver]){
dist[ver][fuel+1]=dist[ver][fuel]+price[ver];
heap.push(state(dist[ver][fuel+1],ver,fuel+1));
}
for(int i=head[ver];~i;i=edges[i].next){
int v=edges[i].v,w=edges[i].w;
if(w<=fuel&&dist[v][fuel-w]>dist[ver][fuel]){
dist[v][fuel-w]=dist[ver][fuel];
heap.push(state(dist[v][fuel-w],v,fuel-w));
}
}
}
return -1;
}
int main()
{
n=read();m=read();
for(int i=0;i<n;i++)price[i]=read();
init();
for(int i=0;i<m;i++){
u=read();v=read();d=read();
add_edges(u,v,d);
}
q=read();
while(q--){
c=read();s=read();e=read();
int t=dijkstra();
if(t==-1)puts("impossible");
else printf("%d\n",t);
}
return 0;
}