我是真的菜...
一开始写了一个裸的bfs ,理所当然的tle了,
考虑如何优化...
考虑对于一个点(i,j)能跳b[i][j]次的含义,就是对于他先花费a[i][j]跳到周围其他某个点上,并且以后还能0花费到达另一个周围的电上,但是总共只能跳b[i][j]次..
考虑一个点拆成300个点,那么他能跳b[i][j],相当于我从当前层(i,j,0)花费了a[i][j]跳到了目标层(i,j,b[i][j]),
然后接下来我能花费为0跳到(i±1,j±1,b[i][j] - 1)这层,然后显而易见从上面的层到下面的层花费均为0.
那么就可以大量优化边数...注意对于考虑点x时,如果他的值已经比三人所在点花费大,直接略过...没加这个优化卡了我一晚上...
c++代码如下:
#include<bits/stdc++.h>
#define lowbit(x) (x & -x)
#define rep(i,x,y) for(register int i = x ;i <= y; ++ i)
#define repd(i,x,y) for(register int i = x ; i >= y ; --i)
typedef long long ll;
template<typename T>inline void read(T&x)
{
x = 0;char c;int sign = 1;
do { c = getchar();if(c == '-') sign = -1; }while(!isdigit(c));
do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));
x *= sign;
}
using namespace std;
const int N = 151,M = 302;
int a[N][N],b[N][N],d[N][N][M],dis[3][3],cnt,ans,idx,n,m;
struct Point { int x,y; }p[3];
struct Str
{
int x,y,z,w;
Str(int x = 0, int y = 0, int z = 0,int w = 0) : x(x), y(y), z(z),w(w) {}
};
int X[4] = {1,-1,0,0};
int Y[4] = {0,0,1,-1};
priority_queue<Str> q;
bool operator < (const Str a,const Str b) { return a.w > b.w; }
void Spfa(int T)
{
rep(i,1,n) rep(j,1,m) rep(k,0,n+m) d[i][j][k] = 1e9;
d[p[T].x][p[T].y][0] = 0;
q.push((Str){p[T].x,p[T].y,0,0});
while(!q.empty())
{
Str x = q.top();q.pop();
bool e = 1;
rep(i,0,2) if(d[p[i].x][p[i].y][0] > x.w) e = 0;
if(e) continue;
if(x.z)
{
rep(i,0,3)
{
int xx = x.x + X[i],yy= x.y + Y[i];
if(!xx || !yy || xx > n || yy > m) continue;
if(d[xx][yy][x.z - 1] > d[x.x][x.y][x.z]) {
d[xx][yy][x.z - 1] = d[x.x][x.y][x.z];
q.push((Str){xx,yy,x.z - 1,d[xx][yy][x.z - 1]});
}
}
if(d[x.x][x.y][x.z - 1] > d[x.x][x.y][x.z]){
d[x.x][x.y][x.z - 1] = d[x.x][x.y][x.z];
q.push((Str){x.x,x.y,x.z - 1,d[x.x][x.y][x.z - 1]});
}
}
else if(b[x.x][x.y])
{
int mx = min(n+m,b[x.x][x.y]);
if(d[x.x][x.y][mx] > d[x.x][x.y][x.z] + a[x.x][x.y]){
d[x.x][x.y][mx] = d[x.x][x.y][x.z] + a[x.x][x.y];
q.push((Str){x.x,x.y,mx,d[x.x][x.y][mx]});
}
}
}
}
int main()
{
ans = 1e9;
read(n); read(m);
rep(i,1,n) rep(j,1,m) read(b[i][j]);
rep(i,1,n) rep(j,1,m) read(a[i][j]);
rep(i,0,2) read(p[i].x),read(p[i].y);
rep(j,0,2)
{
Spfa(j);
rep(i,0,2)
dis[j][i] = d[p[i].x][p[i].y][0];
}
rep(i,0,2)
{
cnt = 0;
rep(j,0,2) cnt += dis[j][i];
if(cnt < ans)
{
ans = cnt;
idx = i;
}
}
if(ans == 1e9) puts("NO");
else printf("%c\n%d\n",idx == 0?'X' : idx == 1 ?'Y':'Z',ans);
return 0;
}