zoukankan      html  css  js  c++  java
  • NOIP2013华容道 大爆搜

    预处理出每个点周围四个点互相到达的最短路,再在整个图上跑SPFA,要记录路径

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #define N 32
     8 using namespace std;
     9 int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
    10 int n,m,g[N][N],dis[N][N][5][5],f[N][N][4];
    11 bool bo[N][N],vis[N][N][4];
    12 int qx[N*N],qy[N*N],fn[N*N],h,t;
    13 int bfs1(int sx,int sy,int tx,int ty,int xx,int yy){
    14     if(tx==sx&&ty==sy)return 0;
    15     memset(bo,0,sizeof bo);
    16     qx[1]=sx;qy[1]=sy;h=t=1;bo[sx][sy]=1;fn[1]=0;
    17     bo[xx][yy]=1;
    18     while(h<=t){
    19         int nx=qx[h],ny=qy[h++];
    20         for(int i=0;i<4;i++)
    21         if(g[nx+dx[i]][ny+dy[i]]&&!bo[nx+dx[i]][ny+dy[i]]){
    22             bo[nx+dx[i]][ny+dy[i]]=1;
    23             qx[++t]=nx+dx[i];qy[t]=ny+dy[i];
    24             fn[t]=fn[h-1]+1;
    25             if(nx+dx[i]==tx&&ny+dy[i]==ty)return fn[t];
    26         }
    27     }return dis[0][0][0][0];
    28 }
    29 void find(int x,int y){
    30     for(int i=0;i<4;i++)if(g[x+dx[i]][y+dy[i]]){
    31         dis[x][y][i][i]=0;
    32         for(int j=i+1;j<4;j++)if(g[x+dx[j]][y+dy[j]]){
    33             int d=bfs1(x+dx[i],y+dy[i],x+dx[j],y+dy[j],x,y);
    34             dis[x][y][i][j]=d;
    35             dis[x][y][j][i]=d;
    36         }
    37     }
    38 }
    39 void init(){
    40     memset(dis,0x3f,sizeof dis);
    41     for(int i=1;i<=n;i++)
    42         for(int j=1;j<=m;j++)if(g[i][j])
    43             find(i,j);
    44 }
    45 
    46 struct data{
    47     int x,y,pos;
    48 }d,ne;
    49 int spfa(int sx,int sy,int tx,int ty){
    50     memset(vis,0,sizeof vis);
    51     if(sx==tx&&sy==ty)return 0;
    52     queue<data> q; while(!q.empty())q.pop();
    53     for(int i=0;i<4;i++)if(g[sx+dx[i]][sy+dy[i]]){
    54         vis[sx+dx[i]][sy+dy[i]][i]=1;
    55         q.push((data){sx+dx[i],sy+dy[i],i});
    56     }
    57     while(!q.empty()){
    58         d=q.front(); vis[d.x][d.y][d.pos]=0; q.pop();
    59         for(int i=0;i<4;i++){
    60             if(g[d.x+dx[i]][d.y+dy[i]]&&f[d.x+dx[i]][d.y+dy[i]][i]>f[d.x][d.y][d.pos]+dis[d.x][d.y][d.pos^1][i]+1){
    61                 f[d.x+dx[i]][d.y+dy[i]][i]=f[d.x][d.y][d.pos]+dis[d.x][d.y][d.pos^1][i]+1;
    62                 if(!vis[d.x+dx[i]][d.y+dy[i]][i]){
    63                     vis[d.x+dx[i]][d.y+dy[i]][i]=1;
    64                     q.push((data){d.x+dx[i],d.y+dy[i],i});
    65                 }
    66             }
    67         }
    68     }
    69     int ans=0x3f3f3f3f;
    70     for(int i=0;i<4;i++)
    71         ans=min(ans,f[tx][ty][i]);
    72     return ans==0x3f3f3f3f?-1:ans;
    73 }
    74 int work(int ex,int ey,int sx,int sy,int tx,int ty){
    75     memset(f,0x3f,sizeof f);
    76     for(int i=0;i<4;i++)
    77         if(g[sx+dx[i]][sy+dy[i]])
    78             f[sx+dx[i]][sy+dy[i]][i]=bfs1(ex,ey,sx+dx[i],sy+dy[i],sx,sy)+1;
    79     return spfa(sx,sy,tx,ty);
    80 }
    81 
    82 int main(){
    83     int q,ex,ey,sx,sy,tx,ty;
    84     scanf("%d%d%d",&n,&m,&q);
    85     for(int i=1;i<=n;i++)
    86         for(int j=1;j<=m;j++)
    87             scanf("%d",&g[i][j]);
    88     init();
    89     while(q--){
    90         scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
    91         printf("%d
    ",work(ex,ey,sx,sy,tx,ty));
    92     }
    93     return 0;
    94 }
    Code
  • 相关阅读:
    設計模式學習(一)觀察者模式(Observer)
    JavaScript對Table進行排序(jQuery)
    一个很好的String组合连接的方法(StringBuffer)
    关于C#静态构造函数的几点说明 (轉載)
    在DataGrid中添加序號
    C# 对象深拷贝、浅铐贝、直接拷贝(转)
    在做數據插入時,傳參數應該注意的小細節!
    JavaScript檢驗時間格式
    獲得鼠標位置(js)
    my tools
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/7746683.html
Copyright © 2011-2022 走看看