UVa11367

来源:互联网 发布:mba培训网络机构 华章 编辑:程序博客网 时间:2024/06/05 06:39

题目链接

简介:
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;}