zoukankan      html  css  js  c++  java
  • JZYZOJ1442 [noip2013]华容道 bfs 最短路 剪枝

    http://172.20.6.3/Problem_Show.asp?id=1442

    想到最短路的简直神了,如果我写我大概只能写一个30分的bfs。

    从数据范围可以看出思路是bfs剪枝,但这里的剪枝是通过最短路的预处理实现的。

    设需要移动的格子为a格子。

    对求最小移动数有意义的移动只有两种,一种是空白格子的移动,一种是a格子移动到空白格子里。

    可以得知要把空白格子移动到a格子旁边然后对a格子进行移动。

    那么我们有了每次查找时进行的预处理1:求空白格子到a格子四周格子的最短路。

    在模拟移动的过程中,可以发现a格子移动的方向是由其旁边的空白格子的位置决定的,对改变a格子移动方向有意义的步数是改变空白格子相对于a格子的方向的步数。

    所以我们就有了预处理2:在查找前预处理出loc[x][y][i][j],即空白格子从格子(x,y)的i方向移动到j方向的最短路。

    需要注意的是,预处理1中求最短路是不能经过a格子所在位置的,同样,其他的bfs或最短路处理也要注意格子移动对所求格子位置的改变,避免改变所求格子位置的情况。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<queue>
      7 using namespace std;
      8 const long long modn=1000000007;
      9 int n,m,d;
     10 int e[40][40]={};
     11 int dis[40][40]={};
     12 int an[40][40][4]={};
     13 int loc[40][40][4][4]={};
     14 int vis[40][40][4]={};
     15 int d1[4]={0,0,1,-1};
     16 int d2[4]={1,-1,0,0};
     17 int ex,ey,sx,sy,tx,ty,ma;
     18 struct pa{
     19     int x;
     20     int y,w;
     21 };
     22 void getit(int xx,int yy){
     23     int x,y;
     24     queue<pa>q;
     25     pa z;
     26     for(int i=0;i<4;i++){
     27         z.x=xx+d1[i];
     28         z.y=yy+d2[i];
     29         memset(dis,63,sizeof(dis));
     30         if(e[z.x][z.y]){
     31             dis[z.x][z.y]=0;
     32             q.push(z);
     33         }
     34         while(!q.empty()){
     35             x=q.front().x;y=q.front().y;q.pop();
     36             for(int i=0;i<4;i++){
     37                 z.x=x+d1[i];
     38                 z.y=y+d2[i];
     39                 if(e[z.x][z.y]&&(z.x!=xx||z.y!=yy)&&dis[z.x][z.y]==ma){
     40                     dis[z.x][z.y]=dis[x][y]+1;
     41                     q.push(z);
     42                 }
     43             }
     44         }
     45         for(int j=0;j<4;j++){
     46             int xx1,yy1;
     47             xx1=xx+d1[j];
     48             yy1=yy+d2[j];
     49             loc[xx][yy][i][j]=dis[xx1][yy1];
     50         }
     51     }
     52 }
     53 void pre(){
     54     pa z;
     55     queue<pa>q;
     56     memset(dis,63,sizeof(dis));
     57     dis[ex][ey]=0;
     58     z.x=ex;
     59     z.y=ey;
     60     q.push(z);
     61     int x,y;
     62     while(!q.empty()){
     63         x=q.front().x;y=q.front().y;q.pop();
     64         for(int i=0;i<4;i++){
     65             z.x=x+d1[i];
     66             z.y=y+d2[i];
     67             if(e[z.x][z.y]&&(z.x!=sx||z.y!=sy)&&dis[z.x][z.y]==ma){
     68                 dis[z.x][z.y]=dis[x][y]+1;
     69                 q.push(z);
     70             }
     71         }
     72     }
     73 }
     74 int bfs(){
     75     if(sx==tx&&sy==ty)return 0;
     76     pre();
     77     queue<pa>q;pa z;
     78     memset(an,63,sizeof(an));
     79     for(int i=0;i<4;i++){
     80         z.x=sx+d1[i];
     81         z.y=sy+d2[i];
     82         z.w=i;
     83         if(e[z.x][z.y]&&dis[z.x][z.y]!=ma){
     84             an[sx][sy][i]=dis[z.x][z.y];
     85             z.x=sx;z.y=sy;
     86             vis[sx][sy][i]=1;
     87             q.push(z);
     88         }
     89     }int x,y,w;
     90     while(!q.empty()){
     91         x=q.front().x;
     92         y=q.front().y;
     93         w=q.front().w;
     94         q.pop();
     95         for(int i=0;i<4;i++){
     96             if(i==w)continue;
     97             z.x=x;z.y=y;z.w=i;
     98             if(e[x+d1[w]][y+d2[w]]&&an[x][y][w]+loc[x][y][w][i]<an[x][y][i]){
     99                 an[x][y][i]=an[x][y][w]+loc[x][y][w][i];
    100                 if(!vis[x][y][i]){
    101                     vis[x][y][i]=1;
    102                     q.push(z);
    103                 }
    104             }
    105         }
    106         z.x=x+d1[w];z.y=y+d2[w];
    107         if(w==0)z.w=1;
    108         else if(w==1)z.w=0;
    109         else if(w==2)z.w=3;
    110         else z.w=2;
    111         if(an[x][y][w]+1<an[z.x][z.y][z.w]){
    112             an[z.x][z.y][z.w]=an[x][y][w]+1;
    113             if(!vis[z.x][z.y][z.w]){
    114                 vis[z.x][z.y][z.w]=1;
    115                 q.push(z);
    116             }
    117         }
    118         vis[x][y][w]=0;
    119     }
    120     int ans=ma;
    121     for(int i=0;i<4;i++){
    122         ans=min(ans,an[tx][ty][i]);
    123     }
    124     if(ans!=ma)return ans;
    125     return -1;
    126 }
    127 int main(){
    128     //freopen("wtf.in","r",stdin);
    129     scanf("%d%d%d",&n,&m,&d);
    130     for(int i=1;i<=n;i++){
    131         for(int j=1;j<=m;j++){
    132             scanf("%d",&e[i][j]);
    133         }
    134     }memset(loc,63,sizeof(loc));
    135     ma=loc[1][1][1][1];
    136     for(int i=1;i<=n;i++){
    137         for(int j=1;j<=m;j++){
    138             getit(i,j);
    139         }
    140     }
    141     for(int i=1;i<=d;i++){
    142         scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
    143         memset(vis,0,sizeof(vis));
    144         printf("%d
    ",bfs());
    145     }
    146     return 0;
    147 }
    View Code
  • 相关阅读:
    Delphi: TMemo垂直滚动条自动显示
    利用百度地图API制作房产酒店地图
    百度地图API--信息窗口
    Echarts饼状图
    JS截取与分割字符串常用技巧总结
    JS DOM1核心概要document
    JS DOM1核心概要1
    phpMVC框架的核心启动类定义
    jquery实现无限滚动瀑布流实现原理
    php连接数据库步骤
  • 原文地址:https://www.cnblogs.com/137shoebills/p/7797923.html
Copyright © 2011-2022 走看看