按照从左上开始、从右上开始、从左下开始、从右下开始四个顺序来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.