Description
飞飞国是一个传说中的国度,国家的居民叫做飞飞侠。飞飞国是一个N×M的矩形方阵,每个格子代表一个街区。
然而飞飞国是没有交通工具的。飞飞侠完全靠地面的弹射装置来移动。
每个街区都装有弹射装置。使用弹射装置是需要支付一定费用的。而且每个弹射装置都有自己的弹射能力。
我们设第i行第j列的弹射装置有Aij的费用和Bij的弹射能力。并规定有相邻边的格子间距离是1。那么,任何飞飞侠都只需要在(i,j)支付Aij的费用就可以任意选择弹到距离不超过Bij的位置了。如下图
(从红色街区交费以后可以跳到周围的任意蓝色街区。)
现在的问题很简单。有三个飞飞侠,分别叫做X,Y,Z。现在它们决定聚在一起玩,于是想往其中一人的位置集合。告诉你3个飞飞侠的坐标,求往哪里集合大家需要花的费用总和最低。
Input
输入的第一行包含两个整数N和M,分别表示行数和列数。
接下来是2个N×M的自然数矩阵,为Bij和Aij
最后一行六个数,分别代表X,Y,Z所在地的行号和列号。
Output
第一行输出一个字符X、Y或者Z。表示最优集合地点。
第二行输出一个整数,表示最小费用。
如果无法集合,只输出一行NO
Sample Input
4 4
0 0 0 0
1 2 2 0
0 2 2 1
0 0 0 0
5 5 5 5
5 5 5 5
5 5 5 5
5 5 5 5
2 1 3 4 2 2
Sample Output
Z
15
Data Constraint
Hint
【数据范围】
20% N, M ≤ 10; Bij ≤ 20
40% N, M ≤ 100; Bij ≤ 20
100% 1 ≤ N, M ≤ 150; 0 ≤ Bij ≤ 10^9; 0 ≤ Aij ≤ 1000
分析:暴力spfa,连边会爆,显然可以带着坐标跑……
代码:
const
maxn=150;
maxv=maxn*maxn;
ymw=100000000000000;
type
node=record
x,y:longint;
end;
var
a,b:array [1..maxn,1..maxn] of int64;
n,m,i,h,t,j:longint;
ans:int64;
x,y:array [1..3] of longint;
dis:array [0..maxn,0..maxn] of int64;
v:array [1..maxn,1..maxn] of boolean;
list:array [1..maxv] of node;
s:array [1..3,1..3] of int64;
ch:char;
procedure init;
var i,j:longint;
begin
readln(n,m);
for i:=1 to n do
for j:=1 to m do
read(a[i,j]);
for i:=1 to n do
for j:=1 to m do
read(b[i,j]);
for i:=1 to 3 do
read(x[i],y[i]);
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x)
else exit(y);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x)
else exit(y);
end;
procedure spfa(xx,yy:longint);
var x,y,i,j:longint;
begin
for i:=1 to n do
for j:=1 to m do
begin
dis[i,j]:=ymw;
v[i,j]:=false;
list[(i-1)*m+j].x:=0;
list[(i-1)*m+j].y:=0;
end;
h:=0; t:=1;
list[t].x:=xx; list[t].y:=yy;
dis[xx,yy]:=0;
v[xx,yy]:=true;
repeat
h:=h mod maxv+1;
x:=list[h].x;
y:=list[h].y;
for i:=max(1,x-a[x,y]) to min(n,x+a[x,y]) do
for j:=max(1,y-a[x,y]+abs(x-i)) to min(m,y+a[x,y]-abs(x-i)) do
if (dis[i,j]>dis[x,y]+b[x,y]) then
begin
dis[i,j]:=dis[x,y]+b[x,y];
if v[i,j]=false then
begin
t:=t mod maxv+1;
list[t].x:=i;
list[t].y:=j;
v[i,j]:=true;
end;
end;
v[x,y]:=false;
until h=t;
end;
begin
init;
for i:=1 to 3 do
begin
spfa(x[i],y[i]);
for j:=1 to 3 do
s[i,j]:=dis[x[j],y[j]];
end;
ans:=maxlongint;
if (s[2,1]<>ymw) and (s[3,1]<>ymw) then
begin
ch:='X';
ans:=s[2,1]+s[3,1];
end;
if (s[1,2]<>ymw) and (s[3,2]<>ymw)
and (s[1,2]+s[3,2]<ans) then
begin
ch:='Y';
ans:=s[1,2]+s[3,2];
end;
if (s[1,3]<>ymw) and (s[2,3]<>ymw)
and (s[1,3]+s[2,3]<ans) then
begin
ch:='Z';
ans:=s[1,3]+s[2,3];
end;
if ans=maxlongint then begin writeln('NO'); exit; end
else
begin
writeln(ch);
writeln(ans);
end;
end.