题目链接
这道题虽然说是网络流24题中的一题,但是我的第一想法确实去用BFS()跑一个最小的花费,但是由于加油的钱、向后走的钱、开设一个新的加油站的钱是不固定的,所以,我们需要进行相应的判断,跑所有可以达到终点的值去比较大小。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 105;
const int dir[4][2] =
{
-1, 0,
0, -1,
0, 1,
1, 0
};
int N, K, A, B, C, mp[maxN][maxN];
int vis[maxN][maxN][11];
struct node
{
int x, y, step, cost;
node(int a=0, int b=0, int c=0, int d=0):x(a), y(b), step(c), cost(d) {}
friend bool operator < (node e1, node e2) { return e1.cost > e2.cost; }
};
queue<node> Q;
bool In_Map(int x, int y) { return x > 0 && y > 0 && x <= N && y <= N; }
inline int bfs()
{
memset(vis, INF, sizeof(vis));
while(!Q.empty()) Q.pop();
Q.push(node(1, 1, K, 0));
vis[1][1][K] = 0;
int ans = INF;
while(!Q.empty())
{
node tmp = Q.front(); Q.pop();
for(int i=0, x, y, step, cost; i<4; i++)
{
x = tmp.x + dir[i][0]; y = tmp.y + dir[i][1]; step = tmp.step - 1; cost = tmp.cost + (i < 2 ? B : 0);
if(!In_Map(x, y)) continue;
if(x == N && y == N) { ans = min(ans, cost); continue; }
if(mp[x][y]) { step = K; cost += A; }
if(!step)
{
step = K; cost += A + C;
if(vis[x][y][step] > cost)
{
vis[x][y][step] = cost;
Q.push(node(x, y, step, cost));
}
continue;
}
if(vis[x][y][step] > cost)
{
vis[x][y][step] = cost;
Q.push(node(x, y, step, cost));
}
}
}
return ans;
}
int main()
{
scanf("%d%d%d%d%d", &N, &K, &A, &B, &C);
for(int i=1; i<=N; i++) for(int j=1; j<=N; j++) scanf("%d", &mp[i][j]);
printf("%d\n", bfs());
return 0;
}