Dijkstra跑了25S差点以为要炸,回头看了一下发现时限是50S。。。。。。。。
难得在BZOJ上找到这么水的题。
NOIP水平不多说了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int inf=1e9;
struct Heapnode{
int x,y,d;
bool operator<(const Heapnode &rhs)const{
return d>rhs.d;
}
};
int d[155][155],A[155][155],B[155][155],n,m;
bool done[155][155];
void dijkstra(int sx,int sy){
priority_queue<Heapnode>q;
memset(d,0x3f,sizeof(d));d[sx][sy]=0;
memset(done,false,sizeof(done));
q.push((Heapnode){sx,sy,0});
while(!q.empty()){
Heapnode tmp=q.top();q.pop();
int x=tmp.x,y=tmp.y;if(done[x][y])continue;
done[x][y]=true;
int l=x-B[x][y],r=x+B[x][y];
for(int i=1;i<=B[x][y];i++){
if(y-i<1)break;
int tmpl=l+i,tmpr=r-i;
tmpl=max(tmpl,1);tmpr=min(tmpr,m);
for(int j=tmpl;j<=tmpr;j++)
if(d[j][y-i]>d[x][y]+A[x][y]){
d[j][y-i]=d[x][y]+A[x][y];
q.push((Heapnode){j,y-i,d[j][y-i]});
}
}
for(int i=1;i<=B[x][y];i++){
if(y+i>m)break;
int tmpl=l+i,tmpr=r-i;
tmpl=max(tmpl,1);tmpr=min(tmpr,m);
for(int j=tmpl;j<=tmpr;j++)
if(d[j][y+i]>d[x][y]+A[x][y]){
d[j][y+i]=d[x][y]+A[x][y];
q.push((Heapnode){j,y+i,d[j][y+i]});
}
}
l=max(l,1);r=min(r,n);
for(int i=l;i<=r;i++)
if(d[i][y]>d[x][y]+A[x][y]){
d[i][y]=d[x][y]+A[x][y];
q.push((Heapnode){i,y,d[i][y]});
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)scanf("%d",&B[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)scanf("%d",&A[i][j]);
int x[3],y[3],ans[3];
for(int i=0;i<3;i++)scanf("%d%d",&x[i],&y[i]);
memset(ans,0,sizeof(ans));
for(int i=0;i<3;i++){
dijkstra(x[i],y[i]);
for(int j=0;j<3;j++)
ans[j]+=d[x[j]][y[j]];
}
int res=1e9,p;
for(int i=0;i<3;i++)
if(ans[i]<res)res=ans[i],p=i;
if(res>=inf){printf("NO");return 0;}
switch(p){
case 0:printf("X");break;
case 1:printf("Y");break;
case 2:printf("Z");break;
}
printf("\n%d",res);
return 0;
}