华容道
Posted ainiyuling
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了华容道相关的知识,希望对你有一定的参考价值。
dfs+spfa
# include<iostream> # include<cstdio> # include<cstring> # include<queue> # define inv inline void # define ini inline int # define is isdigit(ch) # define ge getchar() using namespace std; struct o int x,y,dis; ; int n,m,g,s1,s2,e1,e2,t1,t2,num,tot,minn; int mv1[4]=0,0,1,-1; int mv2[4]=1,-1,0,0; int to[5],en1[5],en2[5],pay[5],h[901]; int d[31][31][31][31][4]; bool use[31][31],vis[31][31],see[31][31],tp[31][31]; bool ll[31][31][31][31]; ini read() int x=0; char ch=ge; while(!is) ch=ge; while(is) x=x*10+ch-48; ch=ge; return x; inv spfa(int x,int y,int k) queue<o>q; d[x][y][x][y][k]=0; q.push((o)x,y,0); while(!q.empty()) o t=q.front(); q.pop(); see[t.x][t.y]=0; for(int i=0;i<4;i++) int xxx=t.x+mv1[i],yyy=t.y+mv2[i]; if(use[xxx][yyy]&&d[x][y][xxx][yyy][k]>d[x][y][t.x][t.y][k]+ll[t.x][t.y][xxx][yyy]&&ll[t.x][t.y][xxx][yyy]) d[x][y][xxx][yyy][k]=d[x][y][t.x][t.y][k]+ll[t.x][t.y][xxx][yyy]; if(!see[xxx][yyy]) see[xxx][yyy]=1; q.push((o)xxx,yyy,0); inv bfs() queue<o>q; q.push((o)e1,e2,0); vis[e1][e2]=0; while(!q.empty()) o t=q.front(); q.pop(); for(int i=0;i<4;i++) int xx=t.x+mv1[i],yy=t.y+mv2[i]; if(vis[xx][yy]) if(xx==s1&&yy==s2) tot++; to[tot]=i; en1[tot]=t.x; en2[tot]=t.y; pay[tot]=t.dis; else vis[xx][yy]=0; q.push((o)xx,yy,t.dis+1); inv dfs(int x,int y,int fa1,int fa2,int go,int tott) if(tott>=minn) return; if(x==t1&&y==t2) minn=tott; return; use[x][y]=0; for(int i=0;i<4;i++) int xx=x+mv1[i],yy=y+mv2[i]; if(d[fa1][fa2][xx][yy][go]<1e5&&use[xx][yy]&&!tp[xx][yy]) tp[xx][yy]=1; dfs(xx,yy,x,y,i,tott+d[fa1][fa2][xx][yy][go]+1); tp[xx][yy]=0; use[x][y]=1; int main() memset(d,1,sizeof(d)); n=read(),m=read(),g=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) use[i][j]=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int k=0;k<4;k++) int xx=i+mv1[k],yy=j+mv2[k]; if(use[xx][yy]) ll[xx][yy][i][j]=1; ll[i][j][xx][yy]=1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int k=0;k<4;k++) int xx=i+mv1[k],yy=j+mv2[k]; if(use[i][j]&&use[xx][yy]) use[xx][yy]=0; spfa(i,j,k); use[xx][yy]=1; while(g--) tot=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) vis[i][j]=use[i][j]; e1=read(),e2=read(),s1=read(),s2=read(),t1=read(),t2=read(); if(s1==t1&&s2==t2) printf("0\n"); continue; bfs(); if(!tot) printf("-1\n"); continue; minn=9999999; for(int i=1;i<=tot;i++) dfs(s1,s2,en1[i],en2[i],to[i],pay[i]); printf("%d\n",(minn==9999999)?-1:minn); return 0;
以上是关于华容道的主要内容,如果未能解决你的问题,请参考以下文章