前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >P4009 汽车加油行驶问题 题解

P4009 汽车加油行驶问题 题解

作者头像
yzxoi
发布2022-09-19 11:57:54
2460
发布2022-09-19 11:57:54
举报
文章被收录于专栏:OI

P4009 汽车加油行驶问题 题解

当然食用spfa啦。 但本蒟蒻不会分层。所以就二维spfa啦。 基本思路就是:一开始先把(1,1)点的状态扔进队列。 然后分类讨论 详细见代码 丑陋无比的代码:

代码语言:javascript
复制
#include<algorithm>
#include<bitset>
#include<complex>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<iterator>
#include<limits>
#include<list>
#include<locale>
#include<map>
#include<memory>
#include<new>
#include<numeric>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<typeinfo>
#include<utility>
#include<valarray>
#include<vector>
#include<cctype>
#include<cerrno>
#include<cfloat>
#include<ciso646>
#include<climits>
#include<clocale>
#include<cmath>
#include<csetjmp>
#include<csignal>
#include<cstdarg>
#include<cstddef>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#define ll long long
#define mod 100003
#define E 1000010
using namespace std;//丑陋的头文件终于结束
inline ll read(){
    ll res=0,f=1;char ch=getchar();
    while(ch<'0'ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar();
    return res*f;
}//丑陋的读优
inline void write(ll x){
    if(x<0) putchar('-'),x=-x;
    if(x<10) putchar(x+'0');
    else{
        write(x/10);
        putchar(x%10+'0');
    }
}//丑陋的输优
//queue<ll> q;
//set<ll> s;
//priority_queue<ll> q1;
//priority_queue<ll,vector<ll>,greater<ll> > q2;
//list<ll> l;
//stack<ll> s;
int n,k,a,b,c;
int has[110][110];//有木有油箱
int dis[110][110][15];//当前状态的最小花费
struct node{
    int x,y,z;//状态记录,分别为x坐标、y坐标、还有多少油
};
struct queue{
    node val[10000000];int s,t;
    void clean(){
        memset(val,0,sizeof(val));
        s=0;t=0;//清空(貌似没有用到过)
    }
    void push(node tmp){
        ++t;
        t%=10000000;
        val[t]=tmp;//加入队尾
    }
    inline node front(){
        return val[(s+1)%10000000];//循环队列,get队首
    }
    void pop(){
        s++;//弹出
        s%=10000000;//循环队列
    }
    bool empty(){//判断是否为空
        if(s>=t) return 1;
        else return 0;
    }
}q;//队列
node make(int x,int y,int z){
    node pp;pp.x=x;pp.y=y;pp.z=z;
    return pp;
}//方便快捷一些
const int dx[]={0,0,1,-1},
          dy[]={1,-1,0,0};//四个方向
void print(){
    system("cls");
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            int ss=2e9;
            for(int l=0;l<=k;l++) ss=min(ss,dis[i][j][l]);
            cout<<ss<<" ";
        }
        cout<<endl;
    }
}//调试输出函数
void spfa(){//spfa开始
    while(!q.empty()){
        node u=q.front();q.pop();
        int x=u.x,y=u.y,K=u.z;//取出队首元素
        if(K==0){//没油了
            if(has[x][y]==1){//真棒!这里就有油箱
                if(dis[x][y][K]+a<dis[x][y][k]){
                    dis[x][y][k]=min(dis[x][y][k],dis[x][y][K]+a);//加油花费a
                    q.push(make(x,y,k));
                }
            }else{//这里没有油箱
                if(dis[x][y][k]>dis[x][y][K]+c+a){
                    dis[x][y][k]=min(dis[x][y][k],dis[x][y][K]+c+a);//新建油箱花费c,加油花费a
                    q.push(make(x,y,k));
                }
            }
        }else{
            if(has[x][y]==1){//坑,如果经过油箱必须加油
                if(dis[x][y][K]+a<dis[x][y][k]){
                    dis[x][y][k]=dis[x][y][K]+a;//愉快的花费a
                    q.push(make(x,y,k));continue ;//因为加油,本次状态取消,直接退出
                }
            }
            for(int i=0;i<4;i++){
                int xx=x+dx[i],yy=y+dy[i];//四个方向
                if(xx>=1&&xx<=n&&yy>=1&&yy<=n){//判断是否越界
                    if(dis[xx][yy][K-1]>dis[x][y][K]+((i==1i==3)?b:0)){//如果往负方向花费b
                        dis[xx][yy][K-1]=dis[x][y][K]+((i==1i==3)?b:0);//更新
                        q.push(make(xx,yy,K-1));//保存状态
                    }
                }
            }

        }
//        print();
    }
}
int main(){
    n=read();k=read();a=read();b=read();c=read();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            has[i][j]=read();
        }
    }//丑陋无比的读入
    memset(dis,63,sizeof(dis));//初始化
    dis[1][1][k]=0;//初始化
    q.push(make(1,1,k));//塞入队列
    spfa();//spfa
    int ans=2e9;//取最小值前设定最大
    for(int i=0;i<=k;i++) ans=min(ans,dis[n][n][i]);//更新,因为终点有很多状态,取最小值
    cout<<ans<<endl;//输出
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-02-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • P4009 汽车加油行驶问题 题解
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档