按照从左上开始、从右上开始、从左下开始、从右下开始四个顺序来Dp,记录路径,如果最小路径不唯一那么这个点的权值为0.
极其考察细心和耐心,数据还是比较弱的……
代码:
program poj2329;
const
maxn=205;
var
i,j,m,p,q,n :longint;
map,f,dp :array[0..maxn,0..maxn]of longint;
rec,g :array[0..maxn,0..maxn]of record x,y:longint;end;
function min(i,j:longint):longint;
begin
if i<j then exit(i);exit(j);
end;
begin
readln(n);
for i:=1 to n do for j:=1 to n do read(map[i,j]);
fillchar(dp,sizeof(dp),127);
for i:=1 to n do
for j:=1 to n do
if map[i,j]<>0 then
begin
dp[i,j]:=0;
rec[i,j].x:=i;
rec[i,j].y:=j;
end else
begin
dp[i,j]:=min(dp[i,j-1],dp[i-1,j])+1;
if dp[i,j]<maxint then
begin
if dp[i,j-1]=dp[i-1,j] then
begin
if (rec[i,j-1].x=rec[i-1,j].x)and(rec[i,j-1].y=rec[i-1,j].y) then
rec[i,j]:=rec[i,j-1] else
begin
rec[i,j].x:=i;
rec[i,j].y:=j;
end;
end else if dp[i,j-1]<dp[i-1,j] then
begin
if (map[i,j-1]=0)and(rec[i,j-1].x=i)and(rec[i,j-1].y=j-1) then
begin
rec[i,j].x:=i;rec[i,j].y:=j;
end else rec[i,j]:=rec[i,j-1];
end else
begin
if (map[i-1,j]=0)and(rec[i-1,j].x=i-1)and(rec[i-1,j].y=j) then
begin
rec[i,j].x:=i;rec[i,j].y:=j;
end else rec[i,j]:=rec[i-1,j];
end;
end;
end;
fillchar(f,sizeof(f),127);
for i:=1 to n do
for j:=1 to n do
begin
g[i,j].x:=0;g[i,j].y:=0;
end;
for i:=1 to n do
for j:=n downto 1 do
if map[i,j]<>0 then
begin
f[i,j]:=0;
g[i,j].x:=i;
g[i,j].y:=j;
end else
begin
f[i,j]:=min(f[i,j+1],f[i-1,j])+1;
if f[i,j]<maxint then
begin
if f[i,j+1]=f[i-1,j] then
begin
if (g[i,j+1].x=g[i-1,j].x)and(g[i,j+1].y=g[i-1,j].y) then
g[i,j]:=g[i,j+1] else
begin
g[i,j].x:=i;
g[i,j].y:=j;
end;
end else if f[i,j+1]<f[i-1,j] then
begin
if (map[i,j+1]=0)and(g[i,j+1].x=i)and(g[i,j+1].y=j+1) then
begin
g[i,j].x:=i;g[i,j].y:=j;
end else g[i,j]:=g[i,j+1];
end else
begin
if (map[i-1,j]=0)and(g[i-1,j].x=i-1)and(g[i-1,j].y=j) then
begin
g[i,j].x:=i;g[i,j].y:=j;
end else g[i,j]:=g[i-1,j];
end;
end;
if f[i,j]<dp[i,j] then
begin
dp[i,j]:=f[i,j];
rec[i,j]:=g[i,j];
end else if f[i,j]=dp[i,j] then
begin
if (rec[i,j].x=0)and(rec[i,j].y=0)then rec[i,j]:=g[i,j];
if ((g[i,j].x<>rec[i,j].x)or(g[i,j].y<>rec[i,j].y))and((g[i,j].x<>0)or(g[i,j].y<>0)) then
begin
rec[i,j].x:=i;rec[i,j].y:=j;
end;
end;
end;
fillchar(f,sizeof(f),127);
for i:=1 to n do
for j:=1 to n do
begin
g[i,j].x:=0;g[i,j].y:=0;
end;
for i:=n downto 1 do
for j:=n downto 1 do
if map[i,j]<>0 then
begin
f[i,j]:=0;
g[i,j].x:=i;
g[i,j].y:=j;
end else
begin
f[i,j]:=min(f[i,j+1],f[i+1,j])+1;
if f[i,j]<maxint then
begin
if f[i,j+1]=f[i+1,j] then
begin
if (g[i,j+1].x=g[i+1,j].x)and(g[i,j+1].y=g[i+1,j].y) then
g[i,j]:=g[i,j+1] else
begin
g[i,j].x:=i;
g[i,j].y:=j;
end;
end else if f[i,j+1]<f[i+1,j] then
begin
if (map[i,j+1]=0)and(g[i,j+1].x=i)and(g[i,j+1].y=j+1) then
begin
g[i,j].x:=i;g[i,j].y:=j;
end else g[i,j]:=g[i,j+1];
end else
begin
if (map[i+1,j]=0)and(g[i+1,j].x=i+1)and(g[i+1,j].y=j) then
begin
g[i,j].x:=i;g[i,j].y:=j;
end else g[i,j]:=g[i+1,j];
end;
end;
if f[i,j]<dp[i,j] then
begin
dp[i,j]:=f[i,j];
rec[i,j]:=g[i,j];
end else if f[i,j]=dp[i,j] then
begin
if (rec[i,j].x=0)and(rec[i,j].y=0)then rec[i,j]:=g[i,j];
if ((g[i,j].x<>rec[i,j].x)or(g[i,j].y<>rec[i,j].y))and((g[i,j].x<>0)or(g[i,j].y<>0)) then
begin
rec[i,j].x:=i;rec[i,j].y:=j;
end;
end;
end;
for i:=1 to n do
for j:=1 to n do
begin
g[i,j].x:=0;g[i,j].y:=0;
end;
fillchar(f,sizeof(f),127);
for i:=n downto 1 do
for j:=1 to n do
if map[i,j]<>0 then
begin
f[i,j]:=0;
g[i,j].x:=i;
g[i,j].y:=j;
end else
begin
f[i,j]:=min(f[i,j-1],f[i+1,j])+1;
if f[i,j]<maxint then
begin
if f[i,j-1]=f[i+1,j] then
begin
if (g[i,j-1].x=g[i+1,j].x)and(g[i,j-1].y=g[i+1,j].y) then
g[i,j]:=g[i,j-1] else
begin
g[i,j].x:=i;
g[i,j].y:=j;
end;
end else if f[i,j-1]<f[i+1,j] then
begin
if (map[i,j-1]=0)and(g[i,j-1].x=i)and(g[i,j-1].y=j-1) then
begin
g[i,j].x:=i;g[i,j].y:=j;
end else g[i,j]:=g[i,j-1];
end else
begin
if (map[i+1,j]=0)and(g[i+1,j].x=i+1)and(g[i+1,j].y=j) then
begin
g[i,j].x:=i;g[i,j].y:=j;
end else g[i,j]:=g[i+1,j];
end;
end;
if f[i,j]<dp[i,j] then
begin
dp[i,j]:=f[i,j];
rec[i,j]:=g[i,j];
end else if f[i,j]=dp[i,j] then
begin
if (rec[i,j].x=0)and(rec[i,j].y=0)then rec[i,j]:=g[i,j];
if ((g[i,j].x<>rec[i,j].x)or(g[i,j].y<>rec[i,j].y))and((g[i,j].x<>0)or(g[i,j].y<>0)) then
begin
rec[i,j].x:=i;rec[i,j].y:=j;
end;
end;
end;
for i:=1 to n do
begin
for j:=1 to n-1 do
write(map[rec[i,j].x,rec[i,j].y],' ');
writeln(map[rec[i,n].x,rec[i,n].y]);
end;
end.