• 洛谷P4009 汽车加油行驶问题


    题目描述

    给定一个 N imes NN×N 的方形网格,设其左上角为起点◎,坐标(1,1)(1,1),XX 轴向右为正, YY 轴向下为正,每个方格边长为 11 ,如图所示。

    一辆汽车从起点◎出发驶向右下角终点▲,其坐标为 (N,N)(N,N)。

    在若干个网格交叉点处,设置了油库,可供汽车在行驶途中加油。汽车在行驶过程中应遵守如下规则:

    1. 汽车只能沿网格边行驶,装满油后能行驶 KK 条网格边。出发时汽车已装满油,在起点与终点处不设油库。

    2. 汽车经过一条网格边时,若其 XX 坐标或 YY 坐标减小,则应付费用 BB ,否则免付费用。

    3. 汽车在行驶过程中遇油库则应加满油并付加油费用 AA。

    4. 在需要时可在网格点处增设油库,并付增设油库费用 CC(不含加油费用AA )。

    5. N,K,A,B,CN,K,A,B,C 均为正整数, 且满足约束: 2leq Nleq 100,2 leq K leq 102N100,2K10。

    设计一个算法,求出汽车从起点出发到达终点所付的最小费用。

    输入输出格式

    输入格式:

    文件的第一行是 N,K,A,B,CN,K,A,B,C 的值。

    第二行起是一个N imes NN×N 的 0-101 方阵,每行 NN 个值,至 N+1N+1 行结束。

    方阵的第 ii 行第 jj 列处的值为 11 表示在网格交叉点 (i,j)(i,j) 处设置了一个油库,为 00 时表示未设油库。各行相邻两个数以空格分隔。

    输出格式:

    程序运行结束时,输出最小费用。

    输入输出样例

    输入样例#1: 
    9 3 2 3 6
    0 0 0 0 1 0 0 0 0
    0 0 0 1 0 1 1 0 0
    1 0 1 0 0 0 0 1 0
    0 0 0 0 0 1 0 0 1
    1 0 0 1 0 0 1 0 0
    0 1 0 0 0 0 0 1 0
    0 0 0 0 1 0 0 0 1
    1 0 0 1 0 0 0 1 0
    0 1 0 0 0 0 0 0 0
    输出样例#1: 
    12

    分层最短路板子题,讲在i行,j列,还剩k油为一个状态,其中建出这个点为k*n*n+i*n+j然后分出加油和跑路,跑一边SPFA即可

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <queue>
    #include <stack>
    #include <vector>
    using namespace std;
    #define MAXN 200100
    #define INF 10000009
    #define MOD 10000007
    #define LL long long
    #define in(a) a=read()
    #define REP(i,k,n) for(int i=k;i<=n;i++)
    #define DREP(i,k,n) for(int i=k;i>=n;i--)
    #define cl(a) memset(a,0,sizeof(a))
    inline int read(){
        int x=0,f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
        return x*f;
    }
    inline void out(int x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) out(x/10);
        putchar(x%10+'0');
    }
    int n,k,a,b,c;
    deque <int> Q;
    int ans=0;
    int dis[MAXN],vis[MAXN];
    int total=0,head[MAXN<<2],nxt[MAXN<<2],to[MAXN<<2],val[MAXN<<2];
    inline int calc(int l,int i,int j){
        return n*n*l+n*i+j;
    }
    inline void adl(int a,int b,int c){
        total++;
        to[total]=b;
        val[total]=c;
        nxt[total]=head[a];
        head[a]=total;
        return ;
    }
    inline void SPFA(){
        memset(dis,127,sizeof(dis));
        Q.push_back(calc(k,0,0));
        dis[calc(k,0,0)]=0;
        vis[calc(k,0,0)]=1;
        while(!Q.empty()){
            int u=Q.front();
            Q.pop_front();
            vis[u]=0;
            for(int e=head[u];e;e=nxt[e])
                if(dis[to[e]]>dis[u]+val[e]){
                    dis[to[e]]=dis[u]+val[e];
                    if(vis[to[e]])  continue;
                    vis[to[e]]=1;
                    if(!Q.empty())
                        if(dis[to[e]]<dis[Q.front()])  Q.push_front(to[e]);
                        else  Q.push_back(to[e]);
                    else  Q.push_back(to[e]);
                }
        }
        return ;
    }
    int main(){
        in(n);in(k);in(a);in(b);in(c);
        REP(i,0,n-1)
            REP(j,0,n-1){
                int x;
                in(x);
                if(x || (!i && !j)){
                    REP(l,0,k-1)  adl(calc(l,i,j),calc(k,i,j),a);
                    if(i!=n-1)  adl(calc(k,i,j),calc(k-1,i+1,j),0);
                    if(j!=n-1)  adl(calc(k,i,j),calc(k-1,i,j+1),0);
                    if(i)  adl(calc(k,i,j),calc(k-1,i-1,j),b);
                    if(j)  adl(calc(k,i,j),calc(k-1,i,j-1),b);
                }
                else{
                    REP(l,0,k-1)  adl(calc(l,i,j),calc(k,i,j),a+c);
                    REP(l,1,k){
                        if(i!=n-1)  adl(calc(l,i,j),calc(l-1,i+1,j),0);
                        if(j!=n-1)  adl(calc(l,i,j),calc(l-1,i,j+1),0);
                        if(i)  adl(calc(l,i,j),calc(l-1,i-1,j),b);
                        if(j)  adl(calc(l,i,j),calc(l-1,i,j-1),b);
                    }
                }
            }
        SPFA();
        ans=INF;
        REP(i,0,k)  ans=min(ans,dis[calc(i,n-1,n-1)]);
        out(ans);
        return 0;
    }
  • 相关阅读:
    Vmware中“重新安装vmware-tools”按钮置灰如何解决
    如何实现Sublime Text3快速生成html代码
    Windows窗体编程你也行
    .NET基础技术总结
    C#考试题第一波
    C#认证题4(使用标准Windons窗体控件)
    通讯录数据库
    C#认证试题(3)
    c#认证题(2)
    c#认证试题
  • 原文地址:https://www.cnblogs.com/jason2003/p/9636646.html
Copyright © 2020-2023  润新知