看了别人的结题报告才过的,可以把没增加一滴油当成一个节点,找最短路就行了。。
#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;
}