[网络流24题-15] 汽车加油行驶 - 分层图
来源:互联网 发布:淘宝电脑配置高价格低 编辑:程序博客网 时间:2024/04/29 20:13
题目描述
给定一个 N*N 的方形网格,设其左上角为起点◎,坐标为(1,1),X 轴向右为正,Y轴向下为正,每个方格边长为1,如图所示。一辆汽车从起点◎出发驶向右下角终点▲,其坐标为(N,N) 。在若干个网格交叉点处,设置了油库,可供汽车在行驶途中加油。汽车在行驶过程中应遵守如下规则:
(1)汽车只能沿网格边行驶,装满油后能行驶 K 条网格边。出发时汽车已装满油,在起点与终点处不设油库。
(2)汽车经过一条网格边时,若其X 坐标或Y 坐标减小,则应付费用B,否则免付费用。
(3)汽车在行驶过程中遇油库则应加满油并付加油费用A。
(4)在需要时可在网格点处增设油库,并付增设油库费用C(不含加油费用A)。
(5)(1)~(4)中的各数N、K、A、B、C均为正整数,且满足约束:2<=N <=100,2 <=K <= 10。
设计一个算法,求出汽车从起点出发到达终点的一条所付费用最少的行驶路线。
对于给定的交通网格,计算汽车从起点出发到达终点的一条所付费用最少的行驶路线。
输入格式
由文件input.txt提供输入数据。文件的第一行是 N,K,A,B,C的值。第二行起是一个 N*N 的 0-1 方阵,每行 N 个值,至 N+1 行结束。方阵的第 i 行第 j 列处的值为 1 表示在网格交叉点(i,j)处设置了一个油库,为0 时表示未设油库。各行相邻两个数以空格分隔。
输出格式
程序运行结束时,将最小费用输出到文件output.txt中。
样例数据
样例输入
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
样例输出
12
题目分析
这题比上题[网络流24题-14] 孤岛营救 - 分层图 简单那么一点点,啧啧啧。
一般使用分层图的特点是有一维比较小,并且去掉限制条件是标准的图论模型,于是按照比较小的那一维分层。
此题就是按照油量分层,建图如下:
1.若当前点是加油站,从当前点当前油量连接一条跨维边至此点满油量,边权为a
2.若当前点不是加油点,且已无油,从当前点连接一条跨维边至此点满油量,边权为a+c(c不包含加油费用)
3.从每个加油点连接一条跨维边至周围四点油量-1处,若横坐标或纵坐标减少,则边权为b,否则边权为0
4.从每个非加油点枚举油量连接一条跨维边至周围四点油量-1处,若横坐标或纵坐标减少,则边权为b,否则边权为0
源代码
#include<algorithm>#include<iostream>#include<iomanip>#include<cstring>#include<cstdlib>#include<vector>#include<cstdio>#include<cmath>#include<queue>using namespace std;inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj;}const int maxn=200005; //数组范围struct Edge { //前向星 int from,to,dist;};struct HeapNode { int d,u; //u为当前结点 bool operator < (HeapNode a) const { return d>a.d; }};struct Dijkstra { int n,m; vector<Edge> edges; //邻接表 vector<int> G[maxn]; //记录每个结点可以到达的结点 bool vst[maxn]; int dist[maxn]; void init(int n) { this->n=n; for(int i=1; i<=n; i++)G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int dist) { edges.push_back((Edge) { from,to,dist }); m=edges.size(); G[from].push_back(m-1); } void main(int s) { //核心算法 priority_queue<HeapNode> Q; for(int i=1; i<=n; i++)dist[i]=0x7fffffff/2; dist[s]=0; memset(vst,0,sizeof(vst)); Q.push((HeapNode) { 0,s }); while(!Q.empty()) { HeapNode Now=Q.top(); Q.pop(); if(vst[Now.u])continue; vst[Now.u]=1; for(int i=0; i<G[Now.u].size(); i++) { Edge& e=edges[G[Now.u][i]]; //边的信息 int Next=e.to; if(dist[Next]>dist[Now.u]+e.dist) { dist[Next]=dist[Now.u]+e.dist; Q.push((HeapNode) { dist[Next],Next }); } } } }} ;Dijkstra dij;int n,Gasoline,a,b,c,map[205][205],ans=0x7fffffff;int GetPos(int x,int y) { //二维坐标 return (x-1)*n+y;}int GetPos(int Gas,int x,int y) { //三维坐标 return (Gasoline-Gas)*n*n+GetPos(x,y);}void Build_Graph() { //按照油量分层 dij.init(n*n*(Gasoline+1)); for(int Gas=0; Gas<Gasoline; Gas++) { //油量 for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(map[i][j])dij.AddEdge(GetPos(Gas,i,j),GetPos(Gasoline,i,j),a); //有加油站,向满油层连跨维边 else if(Gas==0)dij.AddEdge(GetPos(Gas,i,j),GetPos(Gasoline,i,j),a+c); //无加油站,向满油层连跨维边 } const int Dirx[]= {0,1,0,-1,0},Diry[]= {0,0,1,0,-1}; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) for(int k=1; k<=4; k++) { int Nextx=i+Dirx[k],Nexty=j+Diry[k]; if(Nextx<1||Nextx>n||Nexty<1||Nexty>n)continue; if(map[i][j]) { //此处是加油站,从满油层连出跨维边 int Now=GetPos(Gasoline,i,j),Next=GetPos(Gasoline-1,Nextx,Nexty); if(k==3||k==4)dij.AddEdge(Now,Next,b); //倒着走 else dij.AddEdge(Now,Next,0); } else { for(int Gas=1; Gas<=Gasoline; Gas++) { int Now=GetPos(Gas,i,j),Next=GetPos(Gas-1,Nextx,Nexty); if(k==3||k==4)dij.AddEdge(Now,Next,b); //倒着走 else dij.AddEdge(Now,Next,0); } } }}int main() { n=Get_Int(); Gasoline=Get_Int(); a=Get_Int(); b=Get_Int(); c=Get_Int(); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++)map[i][j]=Get_Int(); Build_Graph(); int Start=GetPos(Gasoline,1,1); dij.main(Start); for(int i=0; i<=Gasoline; i++)ans=min(ans,dij.dist[GetPos(i,n,n)]); printf("%d\n",ans); return 0;}
- [网络流24题-15] 汽车加油行驶 - 分层图
- 网络流24题 之十五 汽车加油行驶问题 分层图
- 【线性规划与网络流24题】汽车加油行驶问题 分层图
- 【网络流24题】汽车加油行驶(分层图+最短路)
- loj6223「网络流 24 题」汽车加油行驶问题(分层图spfa)
- 线性规划与网络流24题:《汽车加油行驶问题》
- 【网络流24题】汽车加油行驶问题
- 网络流24题15. 汽车加油行驶问题
- 网络流24题之T15 汽车加油行驶问题
- cogs 737. [网络流24题] 汽车加油行驶
- 汽车加油行驶问题(分层图最短路)
- 【codevs1912】汽车加油行驶问题 分层图最短路
- 汽车行驶加油问题
- 汽车加油行驶问题
- 汽车加油行驶问题
- 汽车加油行驶问题
- 【线性规划与网络流24题 15】汽车加油
- 【dp】汽车加油行驶问题
- hibernate检索策略
- Power of Four
- MVC模式
- 正则表达式
- JSP 学习内置对象:request response session。。。。。的常用方法
- [网络流24题-15] 汽车加油行驶 - 分层图
- 自定义ViewGroup实现流式布局
- 期货投资分析学习--考试
- 双绞线制作
- Hadoop API文档地址
- FPGA中一些概念自己的理解
- pycaffe
- 在nginx中使用lua直接访问mysql和memcaced达到数据接口的统一
- 泛型代码的理解