zoukankan      html  css  js  c++  java
  • [noip2013][codevs3290]华容道 bfs+spfa

    const
            u:array[1..4] of integer=(-1,0,1,0);
            v:array[1..4] of integer=(0,1,0,-1);
            oo=100000000;
    type node=record
          x,y,cs,l:longint;
          end;
    
    
    var
            ft:text;
            n,m,q,ii,i,i1,j1,j,l,w,x,y,x1,y1,x2,y2,x3,y3,es,ey,wei,tou,kx,ky,ans:longint;
            r:array[0..5000000] of node;
            aa,a,fb,fb2:array[0..31,0..31] of longint;
            ff,z,z2:array[0..31,0..31,1..4] of longint;
            f:array[0..31,0..31,1..4,1..4] of longint;
    
            procedure bfs(x,y:longint);
            var i,x1,y1:longint;
            begin
                    wei:=1;
                    tou:=0;
                    r[wei].x:=x;
                    r[wei].y:=y;
                    r[wei].cs:=fb[x,y];
                    while tou<wei do
                    begin
                            inc(tou);
                            for i:=1 to 4 do
                            begin
                                    x1:=r[tou].x+u[i];
                                    y1:=r[tou].y+v[i];
                                    if (a[x1,y1]=1)and(r[tou].cs+1<fb[x1,y1]) then
                                    begin
                                            inc(wei);
                                            r[wei].x:=x1;
                                            r[wei].y:=y1;
                                            r[wei].cs:=r[tou].cs+1;
                                            fb[x1,y1]:=r[wei].cs;
                                    end;
                            end;
                    end;
            end;
    
            begin
                    readln(n,m,q);
                    for i:=1 to n do
                    begin
                            for j:=1 to m do
                            read(a[i,j]);
                            readln;
                    end;
    
                    aa:=a;
                    for i:=1 to n do
                    for j:=1 to m do
                    begin
                            fb2[i,j]:=oo;
                            for l:=1 to 4 do
                            begin
                                    z2[i,j,l]:=oo;
                                    for w:=1 to 4 do f[i,j,l,w]:=oo;
                            end;
                    end;
    
                    for i:=1 to n do
                    for j:=1 to m do
                    if a[i,j]=1 then
                    for l:=1 to 4 do
                    begin
                            x:=i+u[l];
                            y:=j+v[l];
                            if (x>0)and(x<n+1)and(y>0)and(y<m+1)and(a[x,y]=1) then
                            begin
                                    a[x,y]:=0;
                                    fb:=fb2;
                                    fb[i,j]:=1;
                                    bfs(i,j);
                                    for w:=1 to 4 do
                                    begin
                                            x1:=x+u[w];
                                            y1:=y+v[w];
                                            if (x1>0)and(x1<n+1)and(y1>0)and(y1<m+1)and(fb[x1,y1]<oo) then
                                            begin
                                                    f[i,j,l,w]:=fb[x1,y1];
                                            end;
                                    end;
                                    a[x,y]:=1;
                            end;
                    end;
    
            for ii:=1 to q do
            begin
                    read(kx,ky,x,y,es,ey);
                    if (x=es)and(y=ey) then
                    begin
                            writeln(0);
                            continue;
                    end;
                    fb:=fb2;
                    a[x,y]:=0;
                    fb[kx,ky]:=0;
                    bfs(kx,ky);
                    wei:=0;
                    z:=z2;
                    fillchar(ff,sizeof(ff),0);
                    for j:=1 to 4 do
                    begin
                            x1:=x+u[j];
                            y1:=y+v[j];
                            if (x1>0)and(x1<n+1)and(y1>0)and(y1<m+1)and(fb[x1,y1]<oo) then
                            begin
                            inc(wei);
                            r[wei].x:=x;
                            r[wei].y:=y;
                            r[wei].l:=j;
                            z[x,y,j]:=fb[x1,y1];
                            ff[x,y,j]:=1;
                            end;
                    end;
    
                    tou:=0;
                    while tou<wei do
                    begin
                            inc(tou);
                            for i:=1 to 4 do
                            begin
                            x2:=r[tou].x;
                            y2:=r[tou].y;
                            x1:=x2+u[r[tou].l]+u[i];
                            y1:=y2+v[r[tou].l]+v[i];
                            x3:=x2+u[r[tou].l];
                            y3:=y2+v[r[tou].l];
                            if (f[x2,y2,r[tou].l,i]<>oo)and(z[x3,y3,i]>z[x2,y2,r[tou].l]+f[x2,y2,r[tou].l,i]) then
                            begin
                                    z[x3,y3,i]:=z[x2,y2,r[tou].l]+f[x2,y2,r[tou].l,i];
                                    if ff[x3,y3,i]=0 then
                                    begin
                                    ff[x3,y3,i]:=1;
                                    inc(wei);
                                    r[wei].x:=x3;
                                    r[wei].y:=y3;
                                    r[wei].l:=i;
                                    end;
                            end;
                            end;
    
                            ff[r[tou].x,r[tou].y,r[tou].l]:=0;
                    end;
    
                    ans:=oo;
                    for i:=1 to 4 do
                    if z[es,ey,i]<ans then ans:=z[es,ey,i];
                    if ans=oo then writeln(-1)
                    else writeln(ans);
                    a[x,y]:=1;
                    end;
            end.

    因为对棋子的移动最终对应着对空格的移动,而空格的初始位置(非起始情况)一定是在目标棋子的上下左右的。

    这样我们把空格先准备好,然后移动一下棋子,这种操作的代价很容易发现是常数。因此可以使用最短路。方法是把每个棋子一分为四,上下左右,[一个棋 子的左边]就代表了空格的初始位置在这个棋子的左边,即它前一次是从左边移过来的。每个棋子的每一边可以建立于上面棋子的下边,下面棋子的上边等的联系 (用一个有向图来存储),并存储价值。

    最后还有一个小问题,就是每次的q的空白位置不是在目标棋子的上下左右。这时候选择目标棋子的一类,并且修改其与周遭棋子联系的边权,然后做最短路,然后记得要改回去。

  • 相关阅读:
    OAuth2在微服务架构中的应用
    使用SpringSecurity体验OAuth2 (入门2)
    SpringSecurity的配置分析
    SpringSecurity在Springboot下使用的初步体验
    Spring框架中的org.springframework.context.annotation.Import注解类
    使用SpringSecurity体验OAUTH2之一 (入门1)
    5. SpringBoot —— Actuator简介
    无题
    C# 委托的本质
    json 字符串 反序列化
  • 原文地址:https://www.cnblogs.com/victorslave/p/4802135.html
Copyright © 2011-2022 走看看