N*M的迷宮,從起點到終點,求最短距離
寬度優先搜索按照距開始狀態由近及遠的順序進行搜索,因此可以很容易的用來求最短路徑,最少操作之類問題的答案. (可以構造成pair或者編碼成int來表達狀態)
當狀態更加復雜時,就需要封裝成一個類來表示狀態了.
雖然到達終點時就會停止搜索,可如果繼續下去直到隊列為空的話,就可以計算出各個位置的最短距離.此外,如果搜索到最后,d依然為INF的話,便可得知這個位置就是無法從起點發到達的位置.
1 const int INF = 100000000; 2 3 typedef pair<int,int> p;//使用pair表示狀態時,使用typedef會更加方便一些 4 5 char maze[MAX_N][MAX_M+1]; //表示迷宮的字符串的數組 6 int N,M; 7 int sx,sy; //起點坐標 8 int gx,gy; //終點坐標 9 10 int d[MAX_N][MAX_M+1]; //表示迷宮的字符串的數組 11 12 int dx[4]={1,0,-1,0}; //4個方向移動的向量 13 int dy[4]={0,1,0,-1}; 14 15 16 //求從(sx,sy)到(gx,gy)的最短距離 17 //如果無法到達,則是INF 18 int bfs() 19 { 20 queue<P> que; 21 //把所有的位置都初始化為INF 22 for(int i=0; i<N; i++){ 23 for(int j=0; j<M; j++){ 24 d[i][j]=INF;//將起點加入隊列,並把這一地點的距離設置為0 25 } 26 } 27 que.push(P(sx,sy)); 28 d[sx][sy]=0; 29 30 //不斷循環直到隊列的長度為0 31 while(que.size()){ 32 //從隊列的最前端取出元素 33 p=que.front(); 34 que.pop(); 35 //如果取出的狀態已經是終點,則結束搜索 36 if(p.first==gx && p.second==gy) 37 break; 38 //四個方向 39 for(int i=0; i<4; i++){ 40 int nx=p.first+dx[i]; 41 int ny=p.second+dy[i]; 42 //判斷是否可以移動以及是否已經訪問過(d[nx][ny]!=INF即為已經訪問過) 43 if(0<=nx && nx<N && 0<=ny && ny<M && maze[nx][ny]!='#' && d[nx][ny]==INF){ 44 //可以移動的話,則加入到隊列,並且到位置的距離確定為到p的距離+1 45 que.push(P(nx,ny)); 46 d[nx][ny]=d[p.first][p.second]+1; 47 } 48 } 49 } 50 return d[gx][gy]; 51 } 52 53 void solve(){ 54 int ans=bfs(); 55 printf("%d\n",ans); 56 }
