前言:
双向bfs指知道初状态和末状态,从处状态和末状态同时广搜,当一种状态被搜索了两次则说明中间有交织,找到答案。双向BFS一般会比普通BFS快几倍甚至几十倍,当数据较大时。
例题.
八数码:
代码
#include<bits/stdc++.h> #define ll long long using namespace std; int n,g=123804765; short a[4][4],fx,fy,nx,ny; int dx[4]={1,-1,0,0}; int dy[4]={0,0,1,-1}; queue<int> q; map<int,int> v; map<int,int> ans; void solve() { if(n==g) { printf("0"); exit(0); } q.push(n); q.push(g); ans[n]=0; ans[g]=1; v[g]=2; v[n]=1; while(q.size()) { ll now,cur=q.front(); q.pop(); now=cur; for(int i=3;i>=1;i--) for(int j=3;j>=1;j--) { a[i][j]=now%10,now/=10; if(a[i][j]==0) fx=i,fy=j; } for(int i=0;i<4;i++) { nx=fx+dx[i]; ny=fy+dy[i]; if(nx<1 || nx>3 || ny<1 || ny>3) continue ; swap(a[fx][fy],a[nx][ny]); now=0; for(int p=1;p<=3;p++) for(int j=1;j<=3;j++) now=now*10+a[p][j]; if(v[now]==v[cur]) { swap(a[fx][fy],a[nx][ny]); continue; } if(v[now]+v[cur]==3) { printf("%d",ans[cur]+ans[now]); exit(0); } ans[now]=ans[cur]+1; v[now]=v[cur]; q.push(now); swap(a[fx][fy],a[nx][ny]); } } } int main() { cin>>n; solve(); return 0; }
代码应该很好懂。
总结:
如果知道初状态和终状态可以考虑用双向BFS。