LOJ2613 NOIP2013 华容道 【最短路】*

 

LOJ2613 NOIP2013 华容道


LINK


这是个好题,具体题意比较麻烦可以直接看LINK中的链接


然后考虑我们可能的移动方式

首先我们需要把白块移动到需要移动块S的附近(附近四格)

然后我们就可以考虑怎么对S进行移动

  • 操作一:把S和白块互换位置
  • 操作二:把白块从S的一个方向移动到另一方向(方便交换位置)

第一种操作的代价是1很显然,后一种操作我们每次移动的最小代价是可以预处理的

然后我们就可以定义状态x,y,dir表示S在(x,y)且白块在S的dir方向上

我们就只需要考虑在状态之间进行转移,用spfa就够了


  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N 40
  4 #define INF 0x3f3f3f3f
  5 int mx[4]={0,0,1,-1};
  6 int my[4]={1,-1,0,0};
  7 int mv[N][N][4][4];
  8 int dp[N][N][4];
  9 bool inq[N][N][4];
 10 int g[N][N],dis[N][N];
 11 int n,m,q;
 12 int ex,ey,sx,sy,tx,ty;
 13 struct Node1{int x,y;};
 14 struct Node2{int x,y,dir;};
 15 bool check_in(int x,int y){return (x>0&&x<=n&&y>0&&y<=m)&&g[x][y];}
 16 void bfs1(int x,int y,int dir){
 17     if(!check_in(x+mx[dir],y+my[dir]))return;
 18     static queue<Node1> q;
 19     memset(dis,0x3f,sizeof(dis));
 20     dis[x][y]=-1;
 21     dis[x+mx[dir]][y+my[dir]]=0;
 22     q.push((Node1){x+mx[dir],y+my[dir]});
 23     while(!q.empty()){
 24         Node1 now=q.front();q.pop();
 25         for(int i=0;i<4;i++){
 26             int nx=now.x+mx[i];
 27             int ny=now.y+my[i];
 28             if(!check_in(nx,ny))continue;
 29             if(dis[nx][ny]>dis[now.x][now.y]+1){
 30                 dis[nx][ny]=dis[now.x][now.y]+1;
 31                 q.push((Node1){nx,ny});
 32             }
 33         }
 34     }
 35     for(int i=0;i<4;i++){
 36         int nx=x+mx[i];
 37         int ny=y+my[i];
 38         if(check_in(nx,ny))mv[x][y][dir][i]=dis[nx][ny];
 39     }
 40 }
 41 void bfs2(){
 42     memset(dis,0x3f,sizeof(dis));
 43     static queue<Node1> q;
 44     dis[ex][ey]=0;
 45     dis[sx][sy]=-1;
 46     q.push((Node1){ex,ey});
 47     while(!q.empty()){
 48         Node1 now=q.front();q.pop();
 49         for(int i=0;i<4;i++){
 50             int nx=now.x+mx[i];
 51             int ny=now.y+my[i];
 52             if(!check_in(nx,ny))continue;
 53             if(dis[nx][ny]>dis[now.x][now.y]+1){
 54                 dis[nx][ny]=dis[now.x][now.y]+1;
 55                 q.push((Node1){nx,ny});
 56             }
 57         }
 58     }
 59 }
 60 #define NOW now.x][now.y][now.dir
 61 int spfa(){
 62     memset(dp,0x3f,sizeof(dp));
 63     memset(inq,0,sizeof(inq));
 64     static queue<Node2> nq;
 65     for(int i=0;i<4;i++){
 66         int nx=sx+mx[i];
 67         int ny=sy+my[i];
 68         if((!check_in(nx,ny))||dis[sx+mx[i]][sy+my[i]]==INF)continue;
 69         dp[sx][sy][i]=dis[sx+mx[i]][sy+my[i]];
 70         nq.push((Node2){sx,sy,i});
 71         inq[sx][sy][i]=1;
 72     }
 73     while(!nq.empty()){
 74         Node2 now=nq.front();nq.pop();
 75         inq[NOW]=0;
 76         for(int i=0;i<4;i++)
 77             if(dp[now.x][now.y][i]>dp[NOW]+mv[NOW][i]){
 78                 dp[now.x][now.y][i]=dp[NOW]+mv[NOW][i];
 79                 if(!inq[now.x][now.y][i]){
 80                     inq[now.x][now.y][i]=1;
 81                     nq.push((Node2){now.x,now.y,i});
 82                 }
 83             }
 84         int nx=now.x+mx[now.dir];
 85         int ny=now.y+my[now.dir];
 86         if(dp[nx][ny][now.dir^1]>dp[NOW]+1){
 87             dp[nx][ny][now.dir^1]=dp[NOW]+1;
 88             if(!inq[nx][ny][now.dir^1]){
 89                 inq[nx][ny][now.dir^1]=1;
 90                 nq.push((Node2){nx,ny,now.dir^1});
 91             }
 92         }
 93     }
 94     int ans=INF;
 95     for(int i=0;i<4;i++)ans=min(ans,dp[tx][ty][i]);
 96     if(ans==INF)ans=-1;
 97     return ans;
 98 }
 99 int main(){
100     memset(mv,0x3f,sizeof(mv));
101     scanf("%d%d%d",&n,&m,&q);
102     for(int i=1;i<=n;i++)
103         for(int j=1;j<=m;j++)scanf("%d",&g[i][j]);
104     for(int i=1;i<=n;i++)
105         for(int j=1;j<=m;j++)if(g[i][j])
106             for(int k=0;k<4;k++)bfs1(i,j,k);
107     while(q--){
108         scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
109         bfs2();
110         if(sx==tx&&sy==ty)printf("0\n");
111         else printf("%d\n",spfa());
112     }
113     return 0;
114 }

 

posted @ 2018-09-13 19:55  Dream_maker_yk  阅读(154)  评论(0编辑  收藏  举报