看了别人的结题报告才过的,可以把没增加一滴油当成一个节点,找最短路就行了。。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> using namespace std; const int N = 1009; const int M = 10009; const int INF = 0x3f3f3f3f; int dp[N][109]; bool visit[N][109]; int val[N],n,m,q,c,st,en; struct LL{ int to,dis,nex; } L[M<<1]; int F[N],cnt; void add(int f,int t,int d) { L[cnt].dis = d; L[cnt].nex = F[f]; L[cnt].to = t; F[f] = cnt++; } struct node{ int i,h,cost; bool operator <(const node t) const { return cost>t.cost; } }; void init() { scanf("%d%d",&n,&m); memset(F,0,sizeof(F)); cnt = 1; for(int i=0;i<n;i++) scanf("%d",&val[i]); int f,t,d; for(int i=0;i<m;i++) { scanf("%d%d%d",&f,&t,&d); add(f,t,d); add(t,f,d); } } void solve() { scanf("%d%d%d",&c,&st,&en); memset(dp,INF,sizeof(dp)); memset(visit,false,sizeof(visit)); for(int i=0;i<=c;i++) dp[st][i] = val[st]*i; priority_queue<node> que; //visit[st][0] = true; while(!que.empty()) que.pop(); node e,t; e.i = st;e.h = 0;e.cost =0; que.push(e); while(!que.empty()) { e = que.top(); que.pop(); //cout<<e.i<<" "<<e.h<<" "<<e.cost<<endl; if(visit[e.i][e.h]) continue; visit[e.i][e.h] = true; if(e.i==en) { dp[e.i][0] = e.cost; break; } if(e.h<c) { t.i = e.i; t.h = e.h+1; t.cost =e.cost + val[e.i]; que.push(t); } for(int i=F[e.i];i;i=L[i].nex) { int to = L[i].to; if(e.h>=L[i].dis&&!visit[to][e.h-L[i].dis]) { t.i = to; t.h = e.h - L[i].dis; t.cost =e.cost; que.push(t); } } } if(dp[en][0]==INF) printf("impossible\n"); else printf("%d\n",dp[en][0]); } int main() { freopen("in.txt","r",stdin); init(); scanf("%d",&q); while(q--) solve(); return 0; }