It's hard to think about the idea. At the beginning, I thought that SPFA should be pretreated at every point, but it would be very troublesome, and there would be problems
Because empty lattices are different in different directions of each point, we consider abstracting the state into points and storing them in a three-dimensional array
id[i][j][k] indicates that the space is in the K direction of (i,j)
We can deal with the number of steps between States, which can be done with bfs
Connect the sides between the States. Set a start state and end state each time you ask, and connect them to the transferable state respectively
See the code for details
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #define maxn 35 #define M 810005 #define inf 0x3f3f3f3f using namespace std; int n,m,t,a[maxn][maxn],cnt,head[M],dis[maxn][maxn][5][5]; int id[maxn][maxn][5],tot,d[maxn][maxn],ans[M]; int dx[]={1,-1,0,0}; int dy[]={0,0,1,-1}; bool vis[M]; inline int rd(){ int x=0,f=1;char c=' '; while(c<'0' || c>'9') {if(c=='-') f=-1;c=getchar();} while(c<='9' && c>='0') x=x*10+c-'0',c=getchar(); return x*f; } struct EDGE{ int to,nxt,w; }edge[M<<1]; inline void add(int x,int y,int z){ edge[++cnt].to=y; edge[cnt].nxt=head[x]; head[x]=cnt; edge[cnt].w=z; } inline bool judge(int x,int y){ return (x>0 && x<=n && y>0 && y<=m); } queue< pair<int,int> > q; inline int bfs(int x1,int y1,int x2,int y2){ if(x1==x2 && y1==y2) return 0;//Minimum steps from x1,y1 to x2,y2 while(!q.empty()) q.pop(); memset(d,0,sizeof d); q.push(make_pair(x1,y1)); while(!q.empty()){ int x=q.front().first,y=q.front().second; q.pop(); for(int i=0;i<4;i++){ int nx=x+dx[i],ny=y+dy[i]; if(!judge(nx,ny) || !a[nx][ny] || d[nx][ny]) continue; d[nx][ny]=d[x][y]+1; if(nx==x2 && ny==y2) return d[nx][ny]; q.push(make_pair(nx,ny)); } } return inf; } inline void prework(){ for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int k=0;k<4;k++) id[i][j][k]=++tot; memset(dis,0x3f,sizeof dis); for(int i=1;i<=n;i++)//Preprocessing (i,j), the minimum number of steps required for a space to move from its k direction to its t direction for(int j=1;j<=m;j++) if(a[i][j]){ a[i][j]=0; for(int k=0;k<4;k++){ int x=i+dx[k],y=j+dy[k]; if(!judge(x,y) || !a[x][y]) continue; for(int t=0;t<4;t++){ int nx=i+dx[t],ny=j+dy[t]; if(!judge(nx,ny) || !a[nx][ny]) continue; dis[i][j][k][t]=bfs(x,y,nx,ny)+1; } } a[i][j]=1; }//(i,j) the number of steps to move a lattice in k direction, and the state is reversed for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int k=0;k<4;k++) for(int t=0;t<4;t++) if(dis[i][j][k][t]<inf) add(id[i][j][k],id[i+dx[t]][j+dy[t]][t^1],dis[i][j][k][t]); return; } queue<int> Q; inline int SPFA(int s,int t){ memset(ans,0x3f,sizeof ans); memset(vis,0,sizeof vis); while(!Q.empty()) Q.pop(); Q.push(s); vis[s]=1; ans[s]=0; while(!Q.empty()){ int u=Q.front(); Q.pop(); for(int i=head[u];i;i=edge[i].nxt){ int v=edge[i].to; if(ans[v]>ans[u]+edge[i].w){ ans[v]=ans[u]+edge[i].w; if(!vis[v]) vis[v]=1,Q.push(v); } } vis[u]=0; } return ans[t]<inf?ans[t]:-1; } int main(){ n=rd(); m=rd(); t=rd(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=rd(); prework(); while(t--){ int ex=rd(),ey=rd(),sx=rd(),sy=rd(),tx=rd(),ty=rd(); if(!a[sx][sy] || !a[tx][ty] || !a[ex][ey]) {puts("-1");continue;} if(sx==tx && sy==ty) {puts("0");continue;} int S=++tot,T=++tot; a[sx][sy]=0; for(int i=0;i<4;i++){ int x=sx+dx[i],y=sy+dy[i]; if(a[x][y] && judge(x,y)){ int tmp=bfs(ex,ey,x,y);//Empty grid around the starting point if(tmp<inf) add(S,id[sx][sy][i],tmp); } } a[sx][sy]=1; for(int i=0;i<4;i++){ int x=tx+dx[i],y=ty+dy[i]; if(a[x][y] && judge(x,y)) add(id[tx][ty][i],T,0); } printf("%d\n",SPFA(S,T)); } return 0; }