暴力枚举跑三遍堆优化Dijkstra即可
手写堆记得清零
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=155;
const char ch[4]={0,'X','Y','Z'};
const int dx[4]={0,2,3,1},dy[4]={0,3,1,2};
int n,m,siz,tans;
int x[4],y[4];
int v[MAXN][MAXN],t[MAXN][MAXN],ln[MAXN][MAXN],id[MAXN][MAXN];
int ans[4][4];
struct rpg{
int x,y;
}hp[MAXN*MAXN];
void up(int x)
{
for(int i=x,j=i>>1;j;i=j,j>>=1){
if(ln[hp[j].x][hp[j].y]>ln[hp[i].x][hp[i].y]) swap(hp[i],hp[j]),swap(id[hp[i].x][hp[i].y],id[hp[j].x][hp[j].y]);
else break;
}return;
}
void ins(rpg x)
{
hp[++siz]=x;
id[x.x][x.y]=siz;
up(siz);
return;
}
void pop()
{
id[hp[1].x][hp[1].y]=0;
hp[1]=hp[siz--];
id[hp[1].x][hp[1].y]=1;
for(int i=1,j=2;j<=siz;i=j,j<<=1){
if(j<siz&&ln[hp[j+1].x][hp[j+1].y]<ln[hp[j].x][hp[j].y]) ++j;
if(ln[hp[i].x][hp[i].y]>ln[hp[j].x][hp[j].y]) swap(hp[i],hp[j]),swap(id[hp[i].x][hp[i].y],id[hp[j].x][hp[j].y]);
else break;
}return;
}
void Dijkstra(rpg s)
{
memset(ln,0x3f,sizeof(ln));
memset(hp,0,sizeof(hp));
memset(id,0,sizeof(id));
ln[s.x][s.y]=0;ins(s);
while(siz){
rpg nw=hp[1];pop();
int dn=min(n,nw.x+t[nw.x][nw.y]),dm=min(m,nw.y+t[nw.x][nw.y]);
for(int i=max(nw.x-t[nw.x][nw.y],1);i<=dn;++i){
for(int j=max(nw.y-t[nw.x][nw.y],1);j<=dm;++j){
if(abs(nw.x-i)+abs(nw.y-j)>t[nw.x][nw.y]) continue;
if(ln[i][j]<=ln[nw.x][nw.y]+v[nw.x][nw.y]) continue;
ln[i][j]=ln[nw.x][nw.y]+v[nw.x][nw.y];
if(id[i][j]) up(id[i][j]);
else ins((rpg){i,j});
}
}
}return;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
scanf("%d",&t[i][j]);
}
}for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
scanf("%d",&v[i][j]);
}
}for(int i=1;i<=3;++i) scanf("%d%d",&x[i],&y[i]);
for(int i=1;i<=3;++i){
Dijkstra((rpg){x[i],y[i]});
for(int j=1;j<=3;++j) ans[i][j]=ln[x[j]][y[j]];
}tans=min(ans[1][2]+ans[3][2],min(ans[1][3]+ans[2][3],ans[2][1]+ans[3][1]));
if(tans>1e9) puts("NO");
else{
for(int i=1;i<=3;++i){
if(ans[dx[i]][i]+ans[dy[i]][i]==tans){
printf("%c
%d
",ch[i],tans);
return 0;
}
}
}return 0;
}