这题貌似有dalao用了spfa,膜。
蒟蒻只打了记忆化搜索,
设f[x,y,z]表示[1,1]到[x,y],[x,y]颜色为z的最小值花费。
然后就是一波暴搜了,
剪枝:
搜到[x,y]时颜色为z但大于f[x,y,z]就不用继续搜下去。
搜:
①这个点是用魔法去弄的那么离开就要变回去。
下一个点无色而且可用魔法:
②下一个点无色,变成与当前点同色过去,+2过去
③下一个点无色,变成与当前点异色过去,+3过去
下一个点有色:
④与当前点同色,+0过去
⑤与当前点异色,+1过去
const
dx:array [1..4] of integer=(1,-1,0,0);
dy:array [1..4] of integer=(0,0,-1,1);
var
f:array [0..101,0..101,0..1] of longint;
a,b:array [0..101,0..101] of longint;
i,j,n,m,p,q,pq:longint;
function check(aa,bb:longint):boolean;
begin
if (aa<1) or (aa>n) or (bb<1) or (bb>n) then exit(false);
exit(true);
end;
procedure dfs(dep,x,y,rp:longint);
var
i,j,k,l,xx,yy:longint;
begin
j:=a[x,y];
k:=rp;
if b[x,y]<>1 then a[x,y]:=2
else k:=1;
for i:=1 to 4 do
begin
xx:=x+dx[i]; yy:=y+dy[i];
if check(xx,yy) then
begin
if a[xx,yy]<>2 then
begin
if j=a[xx,yy] then
begin
if f[xx,yy,a[xx,yy]]>f[x,y,j]
then begin
f[xx,yy,a[xx,yy]]:=f[x,y,j];
dfs(f[x,y,j],xx,yy,k);
end;
end
else begin
if f[xx,yy,a[xx,yy]]>f[x,y,j]+1
then begin
f[xx,yy,a[xx,yy]]:=f[x,y,j]+1;
dfs(f[x,y,j]+1,xx,yy,k);
end;
end;
end
else if k=1 then
begin
for l:=0 to 1 do
if f[xx,yy,l]>f[x,y,j]+2+abs(j-l) then
begin
f[xx,yy,l]:=f[x,y,j]+2+abs(j-l);
a[xx,yy]:=l;
dfs(f[x,y,j]+2+(j-l),xx,yy,0);
end;
end;
end;
end;
end;
begin
readln(n,m);
for i:=1 to n do
for j:=1 to n do
begin
f[i,j,0]:=maxlongint;
f[i,j,1]:=maxlongint;
a[i,j]:=2;
end;
for i:=1 to m do
begin
readln(p,q,pq);
a[p,q]:=pq;
b[p,q]:=1;
end;
f[1,1,a[1,1]]:=0;
dfs(0,1,1,1);
if (f[n,n,0]=maxlongint) and (f[n,n,1]=maxlongint)
then writeln('-1')
else if f[n,n,0]>f[n,n,1]
then writeln(f[n,n,1])
else writeln(f[n,n,0]);
end.