[网络流24题] 汽车加油行驶问题

题面:

传送门

思路:

汽车油箱最多只能装10格油,因此可以依据油量建立分层图(共11层),然后spfa跑最短路

不用把每一条边都建出来,用的时候判断就好了

没了

真是披着网络流外衣的最短路啊

Code:

 1     #include<iostream>
 2     #include<cstdio>
 3     #include<cstring>
 4     #include<algorithm>
 5     #define inf 1000000000
 6     using namespace std;
 7     inline int read(){
 8         int re=0,flag=1;char ch=getchar();
 9         while(ch>‘9‘||ch<‘0‘){
10             if(ch==‘-‘) flag=-1;
11             ch=getchar();
12         }
13         while(ch>=‘0‘&&ch<=‘9‘) re=(re<<1)+(re<<3)+ch-‘0‘,ch=getchar();
14         return re*flag;
15     }
16     const int dx[5]={0,-1,0,1,0},dy[5]={0,0,-1,0,1};
17     int n,m,k1,k2,k3,a[110][110];
18     int dis[110][110][20];bool vis[110][110][20];
19     struct que{
20         int x,y,z;
21         que(){}
22         que(int xx,int yy,int zz){x=xx;y=yy;z=zz;}
23     };
24     que q[1000010];
25     void spfa(){
26         int i,j,k,x,y,z,tx,ty,tz,tc,head=0,tail=1;
27         for(i=1;i<=n;i++) for(j=1;j<=n;j++) for(k=0;k<=m;k++) dis[i][j][k]=inf;
28         q[0]=que(1,1,m);vis[1][1][m]=1;dis[1][1][m]=0;
29         while(head<tail){
30             x=q[head].x;y=q[head].y;z=q[head++].z;vis[x][y][z]=0;
31     //        cout<<"spfa "<<x<<ends<<y<<ends<<z<<ends<<dis[x][y][z]<<endl;
32             for(i=1;i<=4;i++){
33                 tx=x+dx[i];ty=y+dy[i];
34                 if(tx<1||tx>n||ty<1||ty>n) continue;
35                 tz=(a[tx][ty]?m:(z-1));tc=dis[x][y][z];
36                 if(a[tx][ty]) tc+=k1;
37                 if(i<=2) tc+=k2;
38                 if(z==0) tz=(a[tx][ty]?m:(m-1)),tc+=k3+k1;
39     //            cout<<"    to "<<tx<<ends<<ty<<ends<<tz<<ends<<tc<<ends<<dis[tx][ty][tz]<<endl;
40                 if(tc<dis[tx][ty][tz]){
41                     dis[tx][ty][tz]=tc;
42                     if(!vis[tx][ty][tz]){
43                         q[tail++]=que(tx,ty,tz);vis[tx][ty][tz]=1;
44                     }
45                 }
46             }
47         }
48     }
49     int main(){
50         freopen("trav.in","r",stdin);
51         freopen("trav.out","w",stdout);
52         int i,j,k,ans=inf;
53         n=read();m=read();k1=read();k2=read();k3=read();
54         for(i=1;i<=n;i++) for(j=1;j<=n;j++) a[i][j]=read();
55         spfa();
56     //    for(i=1;i<=n;i++){
57     //        for(j=1;j<=n;j++){
58     //            for(k=0;k<=m;k++) cout<<dis[i][j][k]<<ends;
59     //        }
60     //        cout<<endl;
61     //    }
62         for(i=0;i<=m;i++) ans=min(ans,dis[n][n][i]);
63         printf("%d",ans);
64     }

原文地址:https://www.cnblogs.com/dedicatus545/p/8454349.html

时间: 2024-08-29 17:46:58

[网络流24题] 汽车加油行驶问题的相关文章

网络流24题小结

网络流24题 前言 网络流的实战应用篇太难做了,因此先完善这一部分 ## 第一题:飞行员配对方案 \(BSOJ2542\)--二分图 最优匹配 题意 两国飞行员\(x\)集合\(y\)集合,\(x\)飞行员可以配对特定的\(y\)集合的飞行员(可无),求一对一配对最大数 Solution 二分图最大匹配裸题,最大流实现 建图:(设\(i\in x\)而\(i'\in y\)) \((S,i,1)~(i',T,1)\) 对\((i,j')\)可匹配\((i,j',1)\) Code 略 ## 第二

【线性规划与网络流24题】汽车加油行驶问题 分层图

汽车加油行驶问题 Time Limit: 1 Sec  Memory Limit: 128 MB Description 给定一个 N*N的方形网格,设其左上角为起点◎,坐标为( 1,1),X轴向右为正, Y轴向下为正,每一个方格边长为 1,如图所看到的.一辆汽车从起点◎出发驶向右下角终点▲,其坐标为( N,N).在若干个网格交叉点处,设置了油库,可供汽车在行驶途中加油.汽车在行驶过程中应遵守例如以下规则: (1)汽车仅仅能沿网格边行驶,装满油后能行驶 K条网格边.出发时汽车已装满油,在起点与终

【网络流24题】汽车加油行驶问题(最短路)

[网络流24题]汽车加油行驶问题(最短路) 题面 Cogs 题解 还是SPFA呀... 把剩余的油量直接压进状态里面就好 额外加一个原地加油的决策就行 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map

「网络流24题」 题目列表

「网络流24题」 题目列表 序号 题目标题 模型 题解 1 飞行员配对方案问题 二分图最大匹配 <1> 2 太空飞行计划问题 最大权闭合子图 <2> 3 最小路径覆盖问题 二分图最小路径覆盖 <3> 4 魔术球问题 <4> 5 圆桌问题 <5> 6 最长递增子序列问题 <6> 7 试题库问题 <7> 8 机器人路径规划问题 <8> 9 方格取数问题 二分图最大点权独立集 <9> 10 餐巾计划问题

网络流24题 部分总结

网络流24题 部分总结 慢慢写吧... 以前做过一些了: 然后发现也做了不少了,集中写一下. 警告: 题目按照随机顺序排列. 文章中只有建模的方法. 最小路径覆盖问题 http://cogs.pro:8080/cogs/problem/problem.php?pid=728 题目即题解... // It is made by XZZ #include<cstdio> #include<algorithm> #include<cstring> #define File #

汽车加油行驶问题

汽车加油行驶问题 网络流24题中的,单好像不用费用流水过更快?(我没测过) 广搜搞一下,按剩余油量分层. #include <queue> #include <cstdio> #include <cstring> const int dx[4]= {0,0,1,-1},dy[4]= {1,-1,0,0}; int n,k,a,b,c,g[105][105],dis[105][105][15],ans=0x3f3f3f3f; struct node {int x,y,re

【网络流24题----14】孤岛营救问题

孤岛营救问题 Time Limit: 1 Sec  Memory Limit: 128 MB Description 1944年,特种兵麦克接到国防部的命令.要求马上赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到了迷宫的地形图.迷宫的外形是一个长方形,其南北方向被划分为 N行,东西方向被划分为 M列,于是整个迷宫被划分为 N×M个单元.每个单元的位置可用一个有序数对 (单元的行号,单元的列号)来表示.南北或东西方向相邻的 2个单元之间可能互

【网络流24题】

网络流 网络流24题 [最小路径覆盖问题] 关于输出路径,因为即使有反向弧经过左侧点也一定会改变左侧点的去向,若没连向右侧就会被更新到0,所以不用在意. mark记录有入度的右侧点,然后从没入度的右侧点开始把整条路径输出来即可. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=100000,inf=0x3f3f3f3f; int n,m,

【网络流24题】魔术球问题

P1226 - [网络流24题]魔术球问题 Description 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为 1,2,3,4......的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在n根柱子上最多能放多少个球.例如,在4 根柱子上最多可 放11个球. ′编程任务: 对于给定的n,计算在 n根柱子上最多能放多少个球. Input 第1 行有 1个正整数n,表示柱子数. Output 第一行是球