[CODEVS1912] 汽车加油行驶问题(分层图最短路)

传送门

吐槽:神tm网络流

dis[i][j][k] 表示到 (i, j) 还有 k 油的最优解

然后跑spfa,中间分一大堆情况讨论

1.当前队头还有油

  1.目标点有加油站——直接过去

  2.目标点每加油站——1.直接过去

            2.在当前点召唤一个加油站再过去

2.没油——召唤加油站再走

——代码

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #define N 101
 6 #define min(x, y) ((x) < (y) ? (x) : (y))
 7
 8 inline int read()
 9 {
10     int x = 0, f = 1;
11     char ch = getchar();
12     for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;
13     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;
14     return x * f;
15 }
16
17 int n = read(), k = read(), a = read(), b = read(), c = read(), ans = ~(1 << 31);
18 int map[N][N], dis[N][N][N];
19 int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0}, cos[4] = {0, 0, b, b};
20 bool vis[N][N][N];
21
22 struct node
23 {
24     int x, y, res;
25     node(int x = 0, int y = 0, int res = 0) : x(x), y(y), res(res) {}
26 };
27
28 std::queue <node> q;
29
30 inline void init(int x, int y, int res, int cost)
31 {
32     if(dis[x][y][res] > cost)
33     {
34         dis[x][y][res] = cost;
35         if(!vis[x][y][res])
36         {
37             vis[x][y][res] = 1;
38             q.push(node(x, y, res));
39         }
40     }
41 }
42
43 inline void spfa()
44 {
45     node now;
46     int i, x, y, res, cost;
47     memset(dis, 127 / 3, sizeof(dis));
48     dis[1][1][k] = 0;
49     q.push(node(1, 1, k));
50     while(!q.empty())
51     {
52         now = q.front();
53         q.pop();
54         vis[now.x][now.y][now.res] = 0;
55         for(i = 0; i < 4; i++)
56         {
57             x = now.x + dx[i];
58             y = now.y + dy[i];
59             if(!x || x > n || !y || y > n) continue;
60             cost = dis[now.x][now.y][now.res] + cos[i];
61             if(now.res)
62             {
63                 if(map[x][y]) init(x, y, k, cost + a);
64                 else
65                 {
66                     init(x, y, now.res - 1, cost);
67                     init(x, y, k - 1, cost + a + c);
68                 }
69             }
70             else init(x, y, k - 1, cost + a + c);
71         }
72     }
73 }
74
75 int main()
76 {
77     int i, j;
78     for(i = 1; i <= n; i++)
79         for(j = 1; j <= n; j++)
80             map[i][j] = read();
81     spfa();
82     for(i = 0; i <= k; i++) ans = min(ans, dis[n][n][i]);
83     printf("%d\n", ans);
84     return 0;
85 }

时间: 2024-10-13 23:39:07

[CODEVS1912] 汽车加油行驶问题(分层图最短路)的相关文章

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

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

网络流24题 之十五 汽车加油行驶问题 分层图

题目大意:给出一张网格图,描述了每个点是否是加油站,然后给出以下规则. 1.油量限制,一次加油之后只能行驶k步,向下行驶和向右行驶的时候不增加花费,否则增加B的花费. 2.在没油的时候,若该点没有加油站,就建立一个加油站.花费C. 3.加油花费A. 思路:分层图.f[i][j][k]表示在(i,j)处油箱中还有k的油的时候的最小花费,然后分三种情况更新. (delta = 往回走的B花费) 1.若当前节点有加油站,就必须加油.到下一个节点是还有k - 1的油量,花费last + A + delt

汽车加油行驶(cogs 737)

?问题描述:给定一个N*N 的方形网格,设其左上角为起点◎,坐标为(1,1),X 轴向右为正,Y轴向下为正,每个方格边长为1,如图所示.一辆汽车从起点◎出发驶向右下角终点▲,其坐标为(N,N).在若干个网格交叉点处,设置了油库,可供汽车在行驶途中加油.汽车在行驶过程中应遵守如下规则:(1)汽车只能沿网格边行驶,装满油后能行驶K 条网格边.出发时汽车已装满油,在起点与终点处不设油库.(2)汽车经过一条网格边时,若其X 坐标或Y 坐标减小,则应付费用B,否则免付费用.(3)汽车在行驶过程中遇油库则应

汽车加油行驶问题

汽车加油行驶问题 网络流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题】汽车加油行驶问题(最短路)

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

【网络流24题----15】汽车加油行驶问题

喜闻乐见的分层图最短路,注意到了加油站是强制要加满油的 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 110 10 #

poj3635Full Tank?[分层图最短路]

Full Tank? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7248   Accepted: 2338 Description After going through the receipts from your car trip through Europe this summer, you realised that the gas prices varied between the cities you v

BZOJ 2763 分层图最短路

突然发现我不会分层图最短路,写一发. 就是同层中用双向边相连,用单向边连下一层 1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <string> 5 #include <cstring> 6 #include <queue> 7 #include <vector> 8 #define pa pair<int,int

HDU 5669 Road(线段树建树)(分层图最短路)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5669 [分析]线段树建树+分层图最短路 #include <cstdio> #include <map> #include <algorithm> #include <vector> #include <iostream> #include <set> #include <queue> #include <string&