(Happy Mid-Autumn Festival)博主前来更新c++的BFS。
上篇说了DFS框架和例题,这次说BFS。
先说,思想和用途。
为什么要用到BFS呢?有的时候,对于DFS而言会陷入搜索过深仍然找不到解,也就意味着超时。因此,BFS就来了。尤其在连通性,最短路等问题。
对于BFS而言,会优先考虑每种状态和初始状态的关系。距离初始状态越近,越会被优先考虑,每个时刻(阶段)要做的状态,都是由上个时刻(状态)得来的。
//模板如下
#include<queue>
queue<type> Q;
Q.push(初始状态);
while(!Q.empty()){
type temp=Q.front();
Q.pop();
for(队首可扩展的每种状态){
if(状态合法){
Q.push(状态)
}
}
}
//在这里,要注意一点,主要是当type为结构体的情况。
//STL搭配结构体,以及它们对应的排序规则,一定要会。
接着,上例题马的遍历
上博主,参考部分思路的AC代码。
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=405;
int n,m;
int dx[8]={1,2,2,1,-1,-2,-2,-1},dy[8]={2,1,-1,-2,-2,-1,1,2};
int map[maxn][maxn];
struct point{
int x;
int y;
};
int main(){
point move;
cin>>n>>m>>move.x>>move.y;
// map[move.x][move.y]=0;
queue<point> Q;
Q.push(move);
while(!Q.empty()){
point temp=Q.front();
// cout<<temp.x<<" "<<temp.y<<endl;
Q.pop();
for(int i=0;i<8;i++){
if((temp.x+dx[i]>=1&&temp.x+dx[i]<=n)&&(temp.y+dy[i]>=1&&temp.y+dy[i]<=m)){
int num = map[temp.x][temp.y];
point temp2;
temp2.x=temp.x+dx[i];temp2.y=temp.y+dy[i];
if(map[temp2.x][temp2.y]==0){
Q.push(temp2);
map[temp2.x][temp2.y]=num+1;
}
}
}
}
// cout<<move.x<<" "<<move.y<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==move.x&&j==move.y){
map[i][j]=0;
}
else{
if(map[i][j]==0){
map[i][j]=-1;
}
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
printf("%-5d",map[i][j]);
}
cout<<endl;
}
return 0;
}
其实,还是调试了很久的,删除了一部分调试代码。看思路。
(1)明显的,求最短对吧。容易想到BFS对吧。
(2)刚才强调了STL搭配结构体的使用,要会对吧。
(3)和上一道DFS一样,要注意标记访问,不然还是反复几个点横跳。也就是map数组了。
(4)难点感觉在与,标记到达每个点需要的步数。这个主要依据算法思想,每一步的状态是由上个状态来的。因此,用num取出上一个点的值,如果这个合法,就+1,即可。