记录编号 360348 评测结果 AAAAAAAA
题目名称 [网络流24题] 汽车加油行驶 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 0.081 s
提交时间 2016-12-29 13:57:57 内存使用 1.51 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue> 
using namespace std;
const int N=110; 
int n,k,a,b,c,flag[N][N],dp[N][N][20];
bool vis[N][N][20];
struct sit{
	int x,y,K,d;
	sit(int X=0,int Y=0,int k=0){x=X;y=Y;K=k;d=dp[x][y][k];}
	bool operator > (const sit &x)const{return d>x.d;}
};
priority_queue<sit,vector<sit>,greater<sit> > Q;
void check(int x,int y,int k,int v){
	if (dp[x][y][k]>v)
		dp[x][y][k]=v,Q.push(sit(x,y,k));
}
int main()
{
	freopen("trav.in","r",stdin);
	freopen("trav.out","w",stdout); 
	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",&flag[i][j]);
	memset(dp,0x3f,sizeof dp);
	dp[1][1][k]=0;
	Q.push(sit(1,1,k));
	while (!Q.empty()){
		sit now=Q.top();Q.pop();
		int x=now.x,y=now.y,K=now.K,v=dp[x][y][K];
		if (vis[x][y][K]) continue;
		vis[x][y][K]=1;
		check(x,y,k,v+a+c);//原地加油站 
		if (K==0) continue;
		//向四个方向行进 
		if (x>1){
			if (flag[x-1][y]) check(x-1,y,k,v+a+b);
				else check(x-1,y,K-1,v+b);
		}
		if (y>1){
			if (flag[x][y-1]) check(x,y-1,k,v+a+b);
				else check(x,y-1,K-1,v+b);
		}
		if (x<n){
			if (flag[x+1][y]) check(x+1,y,k,v+a);
				else check(x+1,y,K-1,v);
		}
		if (y<n){
			if (flag[x][y+1]) check(x,y+1,k,v+a);
				else check(x,y+1,K-1,v);
		}
	}
	int ans=dp[n][n][0];
	for (int i=1;i<=k;i++) ans=min(ans,dp[n][n][i]);
	printf("%d\n",ans);
	return 0;
}