zoukankan      html  css  js  c++  java
  • P4009 汽车加油行驶问题

    传送门

    N和K都不大

    可以跑分层图

    设dis[ i ] [ j ] [ k ] 表示从起点到坐标为 i , j 的点,还剩下可以跑 k 步的油时的最少花费

    然后用 Dijkstra 跑分层图

    走下一步时就分开来讨论每种可能的操作

    但是一定要注意每种操作的顺序

    先走,然后考虑走到的这点要不要设加油站,再考虑走到的这点有没有加油站

    如果有加油站,就一定要交钱(强买强卖...)

    发现题目没说每个油库是不是只能用一次

    但是为了最优解显然不能重复用

    所以根本不用考虑之前新设立了哪些加油站

    细节在代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    int n,K,A,B,C;
    int xx[4]={0,1,0,-1},yy[4]={1,0,-1,0};
    int dis[107][107][17];
    int mp[107][107];//存地图状态
    
    struct node
    {
        int x,y,gas,cost;
        bool operator < (const node &b) const{
            return cost>b.cost;
        }
    };
    priority_queue <node> q;
    void Dijk()
    {
        memset(dis,0x7f,sizeof(dis));
        q.push((node){1,1,K,0}); dis[1][1][K]=0;//一开始油是满的,题目限制起点和终点没有油库
        while(!q.empty())
        {
            node u=q.top(); q.pop();
            if(u.cost!=dis[u.x][u.y][u.gas]||!u.gas) continue;//如果没有油了就不能再走,新设油库再加油的操作上一步已经考虑过了
    
            for(int k=0;k<4;k++)
            {
                int x=u.x+xx[k],y=u.y+yy[k],cost=u.cost;
                if(!x||!y||x>n||y>n) continue;//判断越界
                if(x<u.x||y<u.y) cost+=B;//题目要求
    
                if(mp[x][y]&&dis[x][y][K]>cost+A) q.push( (node){x,y,K,dis[x][y][K]=cost+A} );//如果有油库一定要加油
                if(!mp[x][y])
                {
                    if(dis[x][y][u.gas-1]>cost) q.push( (node){x,y,u.gas-1,dis[x][y][u.gas-1]=cost} );//不设油库
                    if(dis[x][y][K]>cost+A+C) q.push( (node){x,y,K,dis[x][y][K]=cost+A+C} );//设油库
                }
            }
        }
    }
    
    int main()
    {
        cin>>n>>K>>A>>B>>C;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&mp[i][j]);
    
        Dijk();
    
        int ans=2e9+7;
        for(int i=0;i<=K;i++)
            ans=min(ans,dis[n][n][i]);//从终点的所有状态里找最优解,当然包括油为0的状态
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    秘密挤奶机(最大流,二分)
    伊基的故事 I
    多源汇最大流(最大流)
    无向树是二分图
    上下界可行流
    圆桌问题(最大流,二分图,网络流24题)
    双栈排序
    观光奶牛
    拜访奶牛
    愤怒的牛&数列分段II
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9699085.html
Copyright © 2011-2022 走看看