CUTRECT - Cắt hình chữ nhật
Tác giả: flashmt
Ngôn ngữ: Pascal
const fi='';
dx:array[1..4] of longint=(-1,0,1,0);
dy:array[1..4] of longint=(0,1,0,-1);
maxn=440;
oo:int64=1000000000;
var m,n,sd,nh:longint;
doc,ngang:array[0..maxn,0..maxn] of longint;
pos,cur,h,p:array[1..maxn*maxn] of longint;
d:array[1..maxn*maxn] of int64;
a,c:array[1..maxn*maxn*4+maxn*4] of longint;
stt:array[0..maxn,0..maxn] of longint;
free:array[1..maxn*maxn] of boolean;
re:int64;
procedure rf;
var i,j:longint;
begin
read(m,n);
if (m=1) and (n=1) then
begin
writeln(-1); halt;
end;
for i:=1 to m do
for j:=1 to n-1 do
read(doc[i,j]);
for i:=1 to m-1 do
for j:=1 to n do
read(ngang[i,j]);
end;
function calc(i,j,ii,jj:longint):longint;
begin
if i=ii then
begin
if j>jj then calc:=ngang[i,j]
else calc:=ngang[i,jj];
end
else
begin
if i>ii then calc:=doc[i,j]
else calc:=doc[ii,j];
end;
end;
procedure init;
var i,j,x,ii,jj,xx,k,sl:longint;
begin
sd:=4;
for i:=1 to m-1 do
for j:=1 to n-1 do
begin
inc(sd);
stt[i,j]:=sd;
end;
for i:=1 to m-1 do
begin
stt[i,0]:=1;
stt[i,n]:=3;
end;
for j:=1 to n-1 do
begin
stt[0,j]:=4;
stt[m,j]:=2;
end;
pos[1]:=1;
for i:=1 to m-1 do
begin
x:=stt[i,1];
a[i]:=x;
c[i]:=ngang[i,1];
end;
pos[2]:=pos[1]+m-1;
for j:=1 to n-1 do
begin
x:=stt[m-1,j];
a[pos[2]+j-1]:=x;
c[pos[2]+j-1]:=doc[m,j];
end;
pos[3]:=pos[2]+n-1;
for i:=1 to m-1 do
begin
x:=stt[i,n-1];
a[pos[3]+i-1]:=x;
c[pos[3]+i-1]:=ngang[i,n];
end;
pos[4]:=pos[3]+m-1;
for j:=1 to n-1 do
begin
x:=stt[1,j];
a[pos[4]+j-1]:=x;
c[pos[4]+j-1]:=doc[1,j];
end;
sl:=n-1;
for i:=1 to m-1 do
for j:=1 to n-1 do
begin
x:=stt[i,j];
pos[x]:=pos[x-1]+sl;
for k:=1 to 4 do
begin
ii:=i+dx[k]; jj:=j+dy[k];
xx:=stt[ii,jj];
a[pos[x]+k-1]:=xx;
c[pos[x]+k-1]:=calc(i,j,ii,jj);
end;
sl:=4;
end;
pos[sd+1]:=pos[sd]+sl;
end;
procedure update(x:longint);
var cha,con:longint;
begin
con:=p[x];
if con=0 then
begin
inc(nh); con:=nh;
end;
cha:=con shr 1;
while (cha>0) and (d[h[cha]]>d[x]) do
begin
h[con]:=h[cha];
p[h[con]]:=con;
con:=cha;
cha:=con shr 1;
end;
h[con]:=x; p[x]:=con;
end;
function pop:longint;
var x,cha,con:longint;
begin
pop:=h[1];
x:=h[nh]; dec(nh);
cha:=1; con:=2;
while (con<=nh) do
begin
if (con<nh) and (d[h[con+1]]<d[h[con]]) then inc(con);
if d[h[con]]>=d[x] then break;
h[cha]:=h[con];
p[h[cha]]:=cha;
cha:=con;
con:=cha shl 1;
end;
h[cha]:=x; p[x]:=cha;
end;
procedure dijk(x:longint);
var i,j,y,t:longint;
begin
for i:=1 to sd do
begin
free[i]:=true;
d[i]:=oo;
end;
fillchar(p,sizeof(p),0);
nh:=0;
d[x]:=0; t:=x;
update(x);
repeat
x:=pop; free[x]:=false;
if (x<>t) and (x<5) then continue;
for i:=pos[x] to pos[x+1]-1 do
begin
y:=a[i];
if d[y]>d[x]+c[i] then
begin
d[y]:=d[x]+c[i];
update(y);
end;
end;
until (not free[3]) or (not free[4]);
if d[3]<re then re:=d[3];
if d[4]<re then re:=d[4];
end;
procedure pr;
begin
oo:=oo*oo;
re:=oo;
dijk(1);
dijk(2);
writeln(re);
end;
begin
assign(input,fi); reset(input);
rf;
init;
pr;
close(input);
end.