简介:
n个城市之间有m条道路,给出起点和终点,以及汽车的油箱容量c
求从s到t的最便宜路径
分析:
从今往后,就用Vjugde啦~\ ( ≧ ▽ ≦ ) /~
显然dp
设计状态:f[i][j]表示到达i,油箱里有j升油的最低花费
之后就用dijkstra转移就好了
每次找到最小的花费状态
枚举下一站以及到达下一站剩下的油量
通过这个计算本站是否要买油
tip
一开始WA了一次,因为数组开小了
改了之后变成了TLE
就把边的记录由邻接矩阵变成了邻接表
然而还是TLE,看前辈在转移的过程中第一次到达T就输出
改过来之后就顺利的A了
//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int INF=0x33333333;
int n,m,p[1005];
int f[1005][103];
int Q,S,T,C,st[1005],tot=0;
bool vis[1005][103];
struct node{
int x,y,v,nxt;
};
node way[200010];
struct heapnode{
int u,c,d;
bool operator < (const heapnode &a) const
{
return d>a.d;
}
};
void add(int u,int w,int z)
{
tot++;
way[tot].x=u;way[tot].y=w;way[tot].v=z;way[tot].nxt=st[u];st[u]=tot;
tot++;
way[tot].x=w;way[tot].y=u;way[tot].v=z;way[tot].nxt=st[w];st[w]=tot;
}
void doit()
{
priority_queue<heapnode> Q;
memset(f,0x33,sizeof(f));
memset(vis,1,sizeof(vis));
for (int i=0;i<=C;i++)
{
f[S][i]=i*p[S];
Q.push((heapnode){S,i,f[S][i]});
}
while (!Q.empty())
{
heapnode now=Q.top(); Q.pop();
if (!vis[now.u][now.c]) continue;
vis[now.u][now.c]=0;
int u=now.u,c=now.c;
if (u==T)
{
printf("%d\n",now.d);
return;
}
for (int i=st[u];i;i=way[i].nxt)
{
int y=way[i].y;
for (int j=0;j<=C-way[i].v;j++)
{
int cc=j+way[i].v; //上一站的油量
if (cc>=c)
{
int cost=(cc-c)*p[u];
if (f[y][j]>now.d+cost)
{
f[y][j]=now.d+cost;
Q.push((heapnode){y,j,f[y][j]});
}
}
}
}
}
printf("impossible\n");
}
int main()
{
memset(st,0,sizeof(st));
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&p[i]);
for (int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
x++; y++;
add(x,y,z);
}
scanf("%d",&Q);
while (Q--)
{
scanf("%d%d%d",&C,&S,&T);
S++; T++;
doit();
}
return 0;
}