记录编号 439626 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2013]华容道 最终得分 100
用户昵称 Gravatar하루Kiev 是否通过 通过
代码语言 C++ 运行时间 0.899 s
提交时间 2017-08-21 11:16:26 内存使用 6.28 MiB
显示代码纯文本
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
#define inf 0x6fffffff
#define size 35
typedef pair<int,int>pos;
int map[size][size],dis[250005],bj[size][size],st[250005],diss[250005];
int zz1,zz,ans;
int n,m,q,ex,ey,sx,sy,tx,ty;
struct node{int to,next,w;}e[250005];
void add(int x,int y,int z){
     e[++zz].to=y;
     e[zz].next=st[x];
     e[zz].w=z;
     st[x]=zz;
}
void bfs(int x,int y,int dx,int dy,int po){
     memset(dis,0,sizeof(dis));
     queue<pos>q;
     q.push(make_pair(x,y));
     dis[bj[x][y]]=1;
     while(!q.empty()){
           int xx=q.front().first,yy=q.front().second;
           if(xx-1>0&&(xx-1!=dx||yy!=dy)&&map[xx-1][yy]&&!dis[bj[xx-1][yy]]){
              q.push(make_pair(xx-1,yy));
              dis[bj[xx-1][yy]]=dis[bj[xx][yy]]+1;
           }
           if(xx+1<=n&&(xx+1!=dx||yy!=dy)&&map[xx+1][yy]&&!dis[bj[xx+1][yy]]){
              q.push(make_pair(xx+1,yy));
              dis[bj[xx+1][yy]]=dis[bj[xx][yy]]+1;
           }
           if(yy-1>0&&(xx!=dx||yy-1!=dy)&&map[xx][yy-1]&&!dis[bj[xx][yy-1]]){
              q.push(make_pair(xx,yy-1));
              dis[bj[xx][yy-1]]=dis[bj[xx][yy]]+1;
           }
           if(yy+1<=m&&(xx!=dx||yy+1!=dy)&&map[xx][yy+1]&&!dis[bj[xx][yy+1]]){
              q.push(make_pair(xx,yy+1));
              dis[bj[xx][yy+1]]=dis[bj[xx][yy]]+1;
           }
           q.pop();
     }
     add(bj[dx][dy]*100+po*3,bj[x][y]*100+(po^1)*3,1);
     if((dx-1!=x||dy!=y)&&dis[bj[dx-1][dy]]){ add(bj[dx][dy]*100+po*3,bj[dx][dy]*100+0*3,dis[bj[dx-1][dy]]-1);/*cout<<po<<" "<<0<<" "<<dis[bj[dx-1][dy]]-1<<endl;*/} 
     if((dx+1!=x||dy!=y)&&dis[bj[dx+1][dy]]){ add(bj[dx][dy]*100+po*3,bj[dx][dy]*100+1*3,dis[bj[dx+1][dy]]-1);/*cout<<po<<" "<<1<<" "<<dis[bj[dx+1][dy]]-1<<endl;*/}
     if((dx!=x||dy-1!=y)&&dis[bj[dx][dy-1]]){ add(bj[dx][dy]*100+po*3,bj[dx][dy]*100+2*3,dis[bj[dx][dy-1]]-1);/*cout<<po<<" "<<2<<" "<<dis[bj[dx][dy-1]]-1<<endl;*/}
     if((dx!=x||dy+1!=y)&&dis[bj[dx][dy+1]]){ add(bj[dx][dy]*100+po*3,bj[dx][dy]*100+3*3,dis[bj[dx][dy+1]]-1);/*cout<<po<<" "<<3<<" "<<dis[bj[dx][dy+1]]-1<<endl;*/}
}
void search(int x,int y,int dx,int dy){
     memset(dis,0,sizeof(dis));
     queue<pos>q;
     queue<int>q1;
     q.push(make_pair(x,y));
     q1.push(1);
     dis[bj[x][y]]=1;
     while(!q.empty()){
           int xx=q.front().first,yy=q.front().second,step=q1.front();
           if(xx-1>0&&(xx-1!=dx||yy!=dy)&&map[xx-1][yy]&&!dis[bj[xx-1][yy]]){
              q.push(make_pair(xx-1,yy));
              dis[bj[xx-1][yy]]=step+1;
              q1.push(step+1);
           }
           if(xx+1<=n&&(xx+1!=dx||yy!=dy)&&map[xx+1][yy]&&!dis[bj[xx+1][yy]]){
              q.push(make_pair(xx+1,yy));
              dis[bj[xx+1][yy]]=step+1;
              q1.push(step+1);
           }
           if(yy-1>0&&(xx!=dx||yy-1!=dy)&&map[xx][yy-1]&&!dis[bj[xx][yy-1]]){
              q.push(make_pair(xx,yy-1));
              dis[bj[xx][yy-1]]=step+1;
              q1.push(step+1);
           }
           if(yy+1>0&&(xx!=dx||yy+1!=dy)&&map[xx][yy+1]&&!dis[bj[xx][yy+1]]){
              q.push(make_pair(xx,yy+1));
              dis[bj[xx][yy+1]]=step+1;
              q1.push(step+1);
           }
           q.pop();
           q1.pop();
     }
}
bool flag[250005];
void spfa(int x,int y){
     memset(diss,0x7f,sizeof(diss));
     queue<int> q;
     if(dis[bj[x-1][y]]){
        q.push(bj[x][y]*100+0*3);
        diss[bj[x][y]*100+0*3]=dis[bj[x-1][y]]-1;
        flag[bj[x][y]*100+0*3]=1;
     }
     if(dis[bj[x+1][y]]){
        q.push(bj[x][y]*100+1*3);
        diss[bj[x][y]*100+1*3]=dis[bj[x+1][y]]-1;
        flag[bj[x][y]*100+1*3]=1;
     }
     if(dis[bj[x][y-1]]){
        q.push(bj[x][y]*100+2*3);
        diss[bj[x][y]*100+2*3]=dis[bj[x][y-1]]-1;
        flag[bj[x][y]*100+2*3]=1;
     }
     if(dis[bj[x][y+1]]){
        q.push(bj[x][y]*100+3*3);
        diss[bj[x][y]*100+3*3]=dis[bj[x][y+1]]-1;
        flag[bj[x][y]*100+3*3]=1;
     }
     while(!q.empty()){
           int k=q.front();
           for(int i=st[k];i;i=e[i].next){
               int t=e[i].to;
               if(diss[t]>diss[k]+e[i].w){
                  diss[t]=diss[k]+e[i].w;
                  if(!flag[t]){
                     flag[t]=1;
                     q.push(t);
                  }
               }
           }
           q.pop();
           flag[k]=0;
     }
}
int main(){
	freopen("PuzzleNOIP2013.in","r",stdin);
	freopen("PuzzleNOIP2013.out","w",stdout);
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=m;j++){
	        scanf("%d",&map[i][j]);
	        bj[i][j]=++zz1;
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(map[i][j]){//从i,j四周出发通向其他四个位置的步数,不可经过i,j 
               if(map[i-1][j]) bfs(i-1,j,i,j,0);//0向上 
               if(map[i+1][j]) bfs(i+1,j,i,j,1);//1向下 
               if(map[i][j-1]) bfs(i,j-1,i,j,2);//2向左 
               if(map[i][j+1]) bfs(i,j+1,i,j,3);//3向右 
			}//搜完一遍后只加边,不保存 
	while(q--){
          scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
          if(sx==tx&&sy==ty) {printf("0\n");continue;}
          search(ex,ey,sx,sy);//确定从ex,ey出发最短路,不经过sx,sy 
          spfa(sx,sy);
          ans=inf;
          ans=min(ans,min(diss[bj[tx][ty]*100+0*3],min(diss[bj[tx][ty]*100+1*3],min(diss[bj[tx][ty]*100+2*3],diss[bj[tx][ty]*100+3*3]))));
          if(ans==inf) printf("-1\n");
          else printf("%d\n",ans);
    }
}