Question:
We know the price of oil at a gas station at each point (that is, the point right), and the length of each route (edge right ).
There are Q inquiries, each of which includes the start point S, end point E, and tank capacity.
The minimum cost from the start point to the end point. If impossible cannot be output, otherwise, the minimum travel cost will be output.
Algorithm:
In fact, the analysis status = is like DP.
The most direct idea is to add the amount of fuel needed to reach the next point at each point. But how can we deal with the problem of how many problems are different?
Therefore, we think of the splitting status, that is, splitting points. Each time a node has more than 1 unit of fuel, then this state is added to the queue. In addition, if the oil in the tank is enough to reach the next point,
Update the status and add the new status to the priority queue.
DP [I] [J] indicates the cost of the remaining fuel in the city I.
Simply put, one dimension is added to the shortest-circuit Algorithm for priority queue optimization.
To consider all possible states,
There are only two operations at each point: 1. 1. One unit of Oil 2. The next point that can be updated.
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<queue>#define maxm 10010#define maxn 1010using namespace std;struct Edge{ int to,val,next;}edge[maxm*2];struct node{ int id,cost,oil; bool operator <(const node &b) const { return cost > b.cost; }};bool vis[maxn][110];int cnt,head[maxn],dp[maxn][110],ans,st,ed,cap,p[maxn];priority_queue<node> q;void add(int x,int y,int z){ edge[cnt].to = y; edge[cnt].val = z; edge[cnt].next = head[x]; head[x] = cnt++;}bool bfs(){ memset(dp,0x3f,sizeof(dp)); memset(vis,0,sizeof(vis)); while(!q.empty()) q.pop(); int id,oil,cost; ans = 0; dp[st][0] = 0; node now,cur,next; now.id = st; now.cost = 0; now.oil = 0; q.push(now); while(!q.empty()) { cur = q.top(); q.pop(); id = cur.id,oil = cur.oil,cost = cur.cost; if(id == ed) { ans = cost; return true; } if(vis[id][oil]) continue; vis[id][oil] = true; if(oil < cap) { next.id = id; next.cost = cost+p[id]; next.oil = oil+1; if(dp[next.id][next.oil]>next.cost && !vis[next.id][next.oil]) { dp[next.id][next.oil] = next.cost; q.push(next); } } for(int i=head[id];i!=-1;i = edge[i].next) { int u = edge[i].to; int w = edge[i].val; if(oil>=w && dp[u][oil-w]>cur.cost && !vis[u][oil-w]) { next.oil = oil-w; next.id = u; next.cost = cost; dp[u][next.oil] = next.cost; q.push(next); } } } return false;}int main(){ int n,m,u,v,l,que; while(scanf("%d%d",&n,&m)!=EOF) { memset(head,-1,sizeof(head)); cnt = 0; for(int i=0;i<n;i++) scanf("%d",&p[i]); for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&l); add(u,v,l); add(v,u,l); } scanf("%d",&que); while(que--) { scanf("%d%d%d",&cap,&st,&ed); if(bfs()) printf("%d\n",ans); else printf("impossible\n"); } } return 0;}