预处理出每个点周围四个点互相到达的最短路,再在整个图上跑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 }