您的位置:首页 > 其它

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

2017-06-13 19:02 399 查看

传送门

 

吐槽:神tm网络流

 

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

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

1.当前队头还有油

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

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

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

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

 

——代码

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 101
#define min(x, y) ((x) < (y) ? (x) : (y))

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 << 1) + (x << 3) + ch - '0';
return x * f;
}

int n = read(), k = read(), a = read(), b = read(), c = read(), ans = ~(1 << 31);
int map

, dis


;
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0}, cos[4] = {0, 0, b, b};
bool vis


;

struct node
{
int x, y, res;
node(int x = 0, int y = 0, int res = 0) : x(x), y(y), res(res) {}
};

std::queue <node> q;

inline void init(int x, int y, int res, int cost)
{
if(dis[x][y][res] > cost)
{
dis[x][y][res] = cost;
if(!vis[x][y][res])
{
vis[x][y][res] = 1;
q.push(node(x, y, res));
}
}
}

inline void spfa()
{
node now;
int i, x, y, res, cost;
memset(dis, 127 / 3, sizeof(dis));
dis[1][1][k] = 0;
q.push(node(1, 1, k));
while(!q.empty())
{
now = q.front();
q.pop();
vis[now.x][now.y][now.res] = 0;
for(i = 0; i < 4; i++)
{
x = now.x + dx[i];
y = now.y + dy[i];
if(!x || x > n || !y || y > n) continue;
cost = dis[now.x][now.y][now.res] + cos[i];
if(now.res)
{
if(map[x][y]) init(x, y, k, cost + a);
else
{
init(x, y, now.res - 1, cost);
init(x, y, k - 1, cost + a + c);
}
}
else init(x, y, k - 1, cost + a + c);
}
}
}

int main()
{
int i, j;
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
map[i][j] = read();
spfa();
for(i = 0; i <= k; i++) ans = min(ans, dis

[i]);
printf("%d\n", ans);
return 0;
}
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: