[NOIP2013]华容道

       

    

   

       

solution:

    一开始打了个70分的暴搜,本来以为有什么特殊的优化,没想到竟然需要预处理,看了看题解QAQ。仔细一看就会发现这道题的特点:所有的询问都是在同一张图上进行的,而这张图又很小(30*30)。所以我们可以先预处理出所有点周围的空格在不经过它的情况下互相能够到达的最短路,这样每一次宽搜就相当于跑一次最短路了。

    

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 #define oo 0x3f3f3f3f
  7 int read() {
  8     int s=0,f=1;
  9     char ch=getchar();
 10     for(; ch>'9'||ch<'0'; ch=getchar()) {
 11         if(ch=='-') {
 12             f=-1;
 13         }
 14     }
 15     for(; ch>='0'&&ch<='9'; ch=getchar()) {
 16         s=(s<<1)+(s<<3)+(ch^48);
 17     }
 18     return s*f;
 19 }
 20 int n,m,q,map[35][35],r[4005],tot,num[35][35][4],sum;
 21 int xx[4]= {1,-1,0,0},yy[4]= {0,0,1,-1};
 22 bool vis[35][35];
 23 struct edge {
 24     int fr,to,next,vv;
 25 } c[40005];
 26 void add(int x,int y,int z) {
 27     c[tot]=(edge) {
 28         x,y,r[x],z
 29     };
 30     r[x]=tot++;
 31 }
 32 int head,tail,fsx[4000005],fsy[4000005],fst[4000005],ex,ey,sx,sy,tx,ty;
 33 int bfs(int fx,int fy,int tx,int ty,int bx,int by) {
 34     if(fx==tx&&fy==ty) {
 35         return 0;
 36     }
 37     memset(vis,0,sizeof(vis));
 38     head=0,tail=1;
 39     fsx[tail]=fx,fsy[tail]=fy,fst[tail]=0;
 40     vis[fx][fy]=true;
 41     while(head<tail) {
 42         int x=fsx[++head],y=fsy[head],t=fst[head];
 43         for(int k=0; k<4; ++k) {
 44             if(map[x+xx[k]][y+yy[k]]&&(x+xx[k]!=bx||y+yy[k]!=by)&&!vis[x+xx[k]][y+yy[k]]) {
 45                 if(x+xx[k]==tx&&y+yy[k]==ty) {
 46                     return t+1;
 47                 }
 48                 fsx[++tail]=x+xx[k];
 49                 fsy[tail]=y+yy[k];
 50                 fst[tail]=t+1;
 51                 vis[x+xx[k]][y+yy[k]]=true;
 52             }
 53         }
 54     }
 55     return oo;
 56 }
 57 int dis[4005];
 58 int queue[4000000];
 59 int spfa() {
 60     if (sx==tx&&sy==ty) return 0;
 61     for (int i=0; i<=tot; ++i) {
 62         dis[i]=oo;
 63     }
 64     for (int k=0; k<4; ++k)
 65         if (num[sx][sy][k]) {
 66             dis[num[sx][sy][k]]=bfs(ex,ey,sx+xx[k],sy+yy[k],sx,sy);
 67             //cout<<sx<<" "<<sy<<" "<<dis[num[sx][sy][k]]<<endl;
 68             queue[k+1]=num[sx][sy][k];
 69         }
 70     /*for(int i=1; i<=4; ++i) {
 71         cout<<dis[queue[i]]<<endl;
 72     }*/
 73     head=1,tail=4;
 74     while (head<=tail) {
 75         int p=queue[head++];
 76         //cout<<p<<endl;
 77         for(int i=r[p]; ~i; i=c[i].next)
 78             if(dis[c[i].to]>dis[p]+c[i].vv) {
 79                 dis[c[i].to]=dis[p]+c[i].vv;
 80                 queue[++tail]=c[i].to;
 81             }
 82     }
 83     int ans=oo;
 84     for(int k=0; k<4; k++) {
 85         if(num[tx][ty][k]) {
 86             ans=min(ans,dis[num[tx][ty][k]]);
 87         }
 88     }
 89     return ans==oo?-1:ans;
 90 }
 91 int Main(){
 92     freopen("PuzzleNOIP2013.in","r",stdin);
 93     freopen("PuzzleNOIP2013.out","w",stdout);
 94     n=read(),m=read(),q=read();
 95     memset(r,-1,sizeof(r));
 96     for(int i=1; i<=n; ++i) {
 97         for(int j=1; j<=m; ++j) {
 98             map[i][j]=read();
 99         }
100     }
101     for(int i=1; i<=n; ++i) {
102         for(int j=1; j<=m; ++j) {
103             for(int k=0; k<4; ++k) {
104                 if(map[i][j]&&map[i+xx[k]][j+yy[k]]) {
105                     num[i][j][k]=++sum;
106                 }
107             }
108         }
109     }
110     for(int i=1; i<=n; ++i) {
111         for(int j=1; j<=m; ++j) {
112             for(int k=0; k<4; ++k) {
113                 if(num[i][j][k]) {
114                     add(num[i][j][k],num[i+xx[k]][j+yy[k]][k^1],1);
115                 }
116             }
117         }
118     }
119     for(int i=1; i<=n; ++i) {
120         for(int j=1; j<=m; ++j) {
121             for(int k=0; k<4; ++k) {
122                 for(int h=0; h<4; ++h) {
123                     if(k!=h&&num[i][j][k]&&num[i][j][h]) {
124                         add(num[i][j][k],num[i][j][h],bfs(i+xx[k],j+yy[k],i+xx[h],j+yy[h],i,j));
125                     }
126                 }
127             }
128         }
129     }
130     for(int i=1; i<=q; ++i) {
131         ex=read(),ey=read(),sx=read(),sy=read(),tx=read(),ty=read();
132         int ans=spfa();
133         printf("%d\n",ans);
134     }
135     return 0;
136 }
137 int hehe=Main();
138 int main() {
139     
140 }

 

posted @ 2017-08-21 15:42  Forever_goodboy  阅读(221)  评论(0编辑  收藏  举报