UVA11367 Full Tank?
题面传送门
二维dj
考虑设di,j为到达i点,还有j升油的最小花费。
那么可以拓展出两种状态,即加1升油或前往下一个城市。
代码实现:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,m,k,x,y,z,d[1039][139],w[1039],cur;
struct yyy{int to,w,z;}tmp;
struct ljb{
int head,h[1039];
yyy f[20039];
inline void add(int x,int y,int z){
f[++head]=(yyy){y,z,h[x]};
h[x]=head;
}
}s;
struct astar{
int to,yo,mo;
bool operator<(const astar &x) const {
return mo>x.mo;
}
};
priority_queue<astar>q;
int main(){
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
memset(s.h,-1,sizeof(s.h));
register int i;
register astar now;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%d",&w[i]);
for(i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
s.add(x+1,y+1,z);s.add(y+1,x+1,z);
}
scanf("%d",&k);
for(i=1;i<=k;i++){
scanf("%d%d%d",&z,&x,&y);
x++;y++;
memset(d,0x3f,sizeof(d));
while(!q.empty()) q.pop();
d[x][0]=0;q.push((astar){x,0,0});
while(!q.empty()){
now=q.top();
if(now.to==y) break;
q.pop();
cur=s.h[now.to];
if(now.yo!=z&&d[now.to][now.yo+1]>now.mo+w[now.to]) d[now.to][now.yo+1]=now.mo+w[now.to],q.push((astar){now.to,now.yo+1,now.mo+w[now.to]});
while(cur!=-1){
tmp=s.f[cur];
if(now.yo>=tmp.w&&d[tmp.to][now.yo-tmp.w]>now.mo)d[tmp.to][now.yo-tmp.w]=now.mo,q.push((astar){tmp.to,now.yo-tmp.w,now.mo});
cur=tmp.z;
}
}
if(now.to!=y) printf("impossible\n");
else printf("%d\n",now.mo);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步