P4009 汽车加油行驶问题

P4009 汽车加油行驶问题

最短路

清一色的spfa....送上一个堆优化Dijkstra吧(貌似代码还挺短)

顺便说一句,堆优化Dj跑分层图灰常好写

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
struct data{ //对于不同题目的要求,我们只需要在结构体中按题意增减变量即可
    int d,x,y,k; //d:费用 x,y:坐标 k:油量
    bool operator < (const data &tmp) const {return d>tmp.d;}
}; priority_queue <data> h;
int d1[4]={0,1,0,-1};
int d2[4]={1,0,-1,0};
int n,tk,a,b,c,ans=2e9,d[12][102][102],oil[102][102];
int main(){
    scanf("%d%d%d%d%d",&n,&tk,&a,&b,&c);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            scanf("%d",&oil[i][j]);
    memset(d,127,sizeof(d));
    h.push((data){d[tk][1][1]=0,1,1,tk}); //优先队列直接放结构体
    while(!h.empty()){
        data u=h.top(); h.pop();
        if(u.d!=d[u.k][u.x][u.y]) continue; //记忆化
        if(!u.k) u.k=tk,u.d+=a+c; //没油了就新建一个油库并加油
        for(int i=0;i<4;++i){
            int r1=u.x+d1[i],r2=u.y+d2[i],cost= i>1 ? b:0; //cost:当向左或向上是要加的费用
            if(r1<1||r1>n||r2<1||r2>n) continue;
            if(oil[r1][r2]){ //有油库必须加满
                if(u.d+cost+a<d[tk][r1][r2]){
                    d[tk][r1][r2]=u.d+cost+a;
                    h.push((data){d[tk][r1][r2],r1,r2,tk});
                }
            }else if(u.d+cost<d[u.k-1][r1][r2]){ //普通的行驶
                d[u.k-1][r1][r2]=u.d+cost;
                h.push((data){d[u.k-1][r1][r2],r1,r2,u.k-1});
            }
        }
    }
    for(int i=0;i<=tk;++i) ans=min(ans,d[i][n][n]); //查找最小值
    printf("%d",ans);
    return 0;
}

 

posted @ 2018-09-21 10:13  kafuuchino  阅读(187)  评论(0编辑  收藏  举报