华容道

Posted ainiyuling

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了华容道相关的知识,希望对你有一定的参考价值。

题面

dfs+spfa

# include<iostream>
# include<cstdio>
# include<cstring>
# include<queue>
# define inv inline void
# define ini inline int
# define is isdigit(ch)
# define ge getchar()
using namespace std;
struct o
    int x,y,dis;
;
int n,m,g,s1,s2,e1,e2,t1,t2,num,tot,minn;
int mv1[4]=0,0,1,-1;
int mv2[4]=1,-1,0,0;
int to[5],en1[5],en2[5],pay[5],h[901];
int d[31][31][31][31][4];
bool use[31][31],vis[31][31],see[31][31],tp[31][31];
bool ll[31][31][31][31];
ini read()

    int x=0;
    char ch=ge;
    while(!is)
    ch=ge;
    while(is)
    
        x=x*10+ch-48;
        ch=ge;
    
    return x;

inv spfa(int x,int y,int k)

    queue<o>q;
    d[x][y][x][y][k]=0;
    q.push((o)x,y,0);
    while(!q.empty())
    
        o t=q.front();
        q.pop();
        see[t.x][t.y]=0;
        for(int i=0;i<4;i++)
          
              int xxx=t.x+mv1[i],yyy=t.y+mv2[i];
              if(use[xxx][yyy]&&d[x][y][xxx][yyy][k]>d[x][y][t.x][t.y][k]+ll[t.x][t.y][xxx][yyy]&&ll[t.x][t.y][xxx][yyy])
              
                  d[x][y][xxx][yyy][k]=d[x][y][t.x][t.y][k]+ll[t.x][t.y][xxx][yyy];
                  if(!see[xxx][yyy])
                  
                      see[xxx][yyy]=1;
                      q.push((o)xxx,yyy,0);
                
            
          
    

inv bfs()

    queue<o>q;
    q.push((o)e1,e2,0);
    vis[e1][e2]=0;
    while(!q.empty())
    
        o t=q.front();
        q.pop();
        for(int i=0;i<4;i++)
          
              int xx=t.x+mv1[i],yy=t.y+mv2[i];
              if(vis[xx][yy])
            if(xx==s1&&yy==s2)
              
                  tot++;
                  to[tot]=i;
                  en1[tot]=t.x;
                  en2[tot]=t.y;
                  pay[tot]=t.dis;
            
              else
              
                  vis[xx][yy]=0;
                  q.push((o)xx,yy,t.dis+1);
            
          
    

inv dfs(int x,int y,int fa1,int fa2,int go,int tott)

    if(tott>=minn) return;
    if(x==t1&&y==t2)
    
        minn=tott;
        return;
    
    use[x][y]=0;
    for(int i=0;i<4;i++)
      
          int xx=x+mv1[i],yy=y+mv2[i];
          if(d[fa1][fa2][xx][yy][go]<1e5&&use[xx][yy]&&!tp[xx][yy])
          
              tp[xx][yy]=1;
              dfs(xx,yy,x,y,i,tott+d[fa1][fa2][xx][yy][go]+1);
              tp[xx][yy]=0;
        
      
    use[x][y]=1;

int main()

    memset(d,1,sizeof(d));
    n=read(),m=read(),g=read();
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        use[i][j]=read();
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
       for(int k=0;k<4;k++)
         
             int xx=i+mv1[k],yy=j+mv2[k];
             if(use[xx][yy])
             
                 ll[xx][yy][i][j]=1;
                 ll[i][j][xx][yy]=1;
            
         
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        for(int k=0;k<4;k++)
          
              int xx=i+mv1[k],yy=j+mv2[k];
             if(use[i][j]&&use[xx][yy])
             
                 use[xx][yy]=0;
                 spfa(i,j,k);
                 use[xx][yy]=1;
            
          
    while(g--)
    
        tot=0;
        for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
            vis[i][j]=use[i][j];
        e1=read(),e2=read(),s1=read(),s2=read(),t1=read(),t2=read();
        if(s1==t1&&s2==t2)
        
            printf("0\n");
            continue;
        
        bfs();
        if(!tot)
        
            printf("-1\n");
            continue;
        
        minn=9999999;
        for(int i=1;i<=tot;i++)
          dfs(s1,s2,en1[i],en2[i],to[i],pay[i]);
        printf("%d\n",(minn==9999999)?-1:minn);
    
    return 0;

  

以上是关于华容道的主要内容,如果未能解决你的问题,请参考以下文章

[Noip2013]华容道

NOIP2013华容道

NOIP 华容道

NOIP2013 华容道

[NOIP2013]华容道

[RT][NOIP2013]华容道