宽度优先搜索与深度优先搜索一样,都会生成所有能遍历到的状态,因此需要对所有状态进行处理时使用宽度优先搜索也是可以的。但是递归函数可以很简短地编写,而且状态的管理也更简单,所以大多数情况下还是使用深度优先搜索实现。反之,在求最短路时,深度优先搜索需要反复经过相同的状态,所以此时还是使用宽度优先搜索比较好。
宽度优先搜索会把状态逐个加入队列,因此通常需要与状态数成正比的内存空间。深度优先搜索是与最大的递归深度成正比的,一般与状态数相比,递归的深度不会太大,所以可以认为深度优先搜索更加节省空间。
理论上bfs和dfs的最坏时间复杂度都是:状态数*转移方向,但实际证明,求最短路径要用bfs,dfs在大多数题中都超时了。当状态复杂时,用结构体表示。方向较多时,用数组+循环表示。
#include <iostream>
#include<cmath>
#include<queue>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int N,K,MIN=10000000;
struct node{
int p,time;
}Node;
bool vis[1000001]={false};
void dfs(int pos,int time) {//超时了
printf("%d",pos);
system("pause");
if(pos==K) {
if(time<MIN) MIN=time;
return;
}
if(pos*2>=0&&pos*2<=100000&&vis[pos*2]==false){
vis[pos*2]=true;
dfs(pos*2,time+1);
vis[pos*2]=false;
}
if(pos+1>=0&&pos+1<=100000&&vis[pos+1]==false){
vis[pos+1]=true;
dfs(pos+1,time+1);
vis[pos+1]=false;
}
if(pos-1>=0&&pos-1<=100000&&vis[pos-1]==false){
vis[pos-1]=true;
dfs(pos-1,time+1);
vis[pos-1]=false;
}
}
void bfs(){
queue<node> q;
Node.p=N;Node.time=0;
vis[N]=true;
q.push(Node);
while(!q.empty()){
node t=q.front();
q.pop();
if(t.p==K){
MIN=t.time;
return;
}
if(t.p*2>=0&&t.p*2<=100000&&vis[t.p*2]==false){
Node.p=t.p*2;Node.time=t.time+1;
vis[t.p*2]=true;
q.push(Node);
}
if(t.p+1>=0&&t.p+1<=100000&&vis[t.p+1]==false){
Node.p=t.p+1;Node.time=t.time+1;
vis[t.p+1]=true;
q.push(Node);
}
if(t.p-1>=0&&t.p-1<=100000&&vis[t.p-1]==false){
Node.p=t.p-1;Node.time=t.time+1;
vis[t.p-1]=true;
q.push(Node);
}
}
}
int main(int argc, char** argv) {
scanf("%d %d",&N,&K);
bfs();
//dfs(N,0);
printf("%d",MIN);
return 0;
}