NOIP2013华容道 大爆搜

来源:互联网 发布:科学网 博弈 复杂网络 编辑:程序博客网 时间:2024/05/16 11:22

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

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#include<queue>#define N 32using namespace std;int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};int n,m,g[N][N],dis[N][N][5][5],f[N][N][4];bool bo[N][N],vis[N][N][4];int qx[N*N],qy[N*N],fn[N*N],h,t;int bfs1(int sx,int sy,int tx,int ty,int xx,int yy){if(tx==sx&&ty==sy)return 0;memset(bo,0,sizeof bo);qx[1]=sx;qy[1]=sy;h=t=1;bo[sx][sy]=1;fn[1]=0;bo[xx][yy]=1;while(h<=t){int nx=qx[h],ny=qy[h++];for(int i=0;i<4;i++)if(g[nx+dx[i]][ny+dy[i]]&&!bo[nx+dx[i]][ny+dy[i]]){bo[nx+dx[i]][ny+dy[i]]=1;qx[++t]=nx+dx[i];qy[t]=ny+dy[i];fn[t]=fn[h-1]+1;if(nx+dx[i]==tx&&ny+dy[i]==ty)return fn[t];}}return dis[0][0][0][0];}void find(int x,int y){for(int i=0;i<4;i++)if(g[x+dx[i]][y+dy[i]]){dis[x][y][i][i]=0;for(int j=i+1;j<4;j++)if(g[x+dx[j]][y+dy[j]]){int d=bfs1(x+dx[i],y+dy[i],x+dx[j],y+dy[j],x,y);dis[x][y][i][j]=d;dis[x][y][j][i]=d;}}}void init(){memset(dis,0x3f,sizeof dis);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(g[i][j])find(i,j);}struct data{int x,y,pos;}d,ne;int spfa(int sx,int sy,int tx,int ty){memset(vis,0,sizeof vis);if(sx==tx&&sy==ty)return 0;queue<data> q; while(!q.empty())q.pop();for(int i=0;i<4;i++)if(g[sx+dx[i]][sy+dy[i]]){vis[sx+dx[i]][sy+dy[i]][i]=1;q.push((data){sx+dx[i],sy+dy[i],i});}while(!q.empty()){d=q.front(); vis[d.x][d.y][d.pos]=0; q.pop();for(int i=0;i<4;i++){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){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;if(!vis[d.x+dx[i]][d.y+dy[i]][i]){vis[d.x+dx[i]][d.y+dy[i]][i]=1;q.push((data){d.x+dx[i],d.y+dy[i],i});}}}}int ans=0x3f3f3f3f;for(int i=0;i<4;i++)ans=min(ans,f[tx][ty][i]);return ans==0x3f3f3f3f?-1:ans;}int work(int ex,int ey,int sx,int sy,int tx,int ty){memset(f,0x3f,sizeof f);for(int i=0;i<4;i++)if(g[sx+dx[i]][sy+dy[i]])f[sx+dx[i]][sy+dy[i]][i]=bfs1(ex,ey,sx+dx[i],sy+dy[i],sx,sy)+1;return spfa(sx,sy,tx,ty);}int main(){int q,ex,ey,sx,sy,tx,ty;scanf("%d%d%d",&n,&m,&q);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&g[i][j]);init();while(q--){scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);printf("%d\n",work(ex,ey,sx,sy,tx,ty));}return 0;}


原创粉丝点击