本题和第14题一样都是分层图的最短路,但是本题比14题简单一些,因为不存在14题那种对应的钥匙开对应的门的情况,所以本题并不需要状态压缩,只用bfs一遍,在bfs的同时按照题目的要求,分三种情况进行更新最短路就行(注意如果没有油啦就一定要continue,跳过这个,下一个有油继续进队)。最后同样for一遍循环,选出所有答案中的最优解就行。
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#define M 105
#define INF 0x7fffffff/2
using namespace std;
int dp[M][M][15];
int fmap[M][M];
int fx[5]={0,-1,0,1,0};
int fy[5]={0,0,1,0,-1};
int n,k,a,b,c;
struct node
{
int x;
int y;
int oil;
int cost;
}str1,str2;
queue <node> q;
void init()
{
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",&fmap[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int l=0;l<=k;l++)
dp[i][j][l]=INF;
}
void bfs()
{
str1.x=1;
str1.y=1;
str1.cost=0;
str1.oil=k;
q.push(str1);
dp[1][1][k]=0;
while(!q.empty())
{
str1=q.front();
q.pop();
if(str1.oil==0)
continue;
for(int i=1;i<=4;i++)
{
str2.x=str1.x+fx[i];
str2.y=str1.y+fy[i];
if(str2.x>=1&&str2.x<=n&&str2.y>=1&&str2.y<=n)
{
str2.oil=str1.oil-1;
str2.cost=str1.cost;
if(str2.x<str1.x||str2.y<str1.y)
str2.cost+=b;
if(fmap[str2.x][str2.y]==1)
{
str2.cost+=a;
str2.oil=k;
}
if(str2.cost<dp[str2.x][str2.y][str2.oil])
{
dp[str2.x][str2.y][str2.oil]=str2.cost;
q.push(str2);
}
if(!fmap[str2.x][str2.y])
{
str2.oil=k;
str2.cost+=(a+c);
}
if(str2.cost<dp[str2.x][str2.y][str2.oil])
{
dp[str2.x][str2.y][str2.oil]=str2.cost;
q.push(str2);
}
}
}
}
}
int main()
{
freopen("t15.in","r",stdin);
freopen("t15.out","w",stdout);
init();
bfs();
int ans=INF;
for(int i=0;i<=k;i++)
{
if(ans>dp[n][n][i])
ans=dp[n][n][i];
}
printf("%d\n",ans);
return 0;
}