搜索
深度优先搜索($DFS$),广度优先搜索($BFS$)

对比:
|
数据结构 |
空间 |
|
| $DFS$ |
$stack$ |
$O(h)$ |
不具最短性 |
| $BFS$ |
$queue$ |
$O(2^h)$ |
最短路 |
$DFS$:
例1:给定一个数字$n$,输出$1\sim n$的全排列(按字典序)
考虑顺序与回溯

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include<bits/stdc++.h> using namespace std;
const int N=10; int n; int num[N]; bool use[N]; void dfs(int now){ if(now>n){ for(int i=1;i<=n;i++){ cout << num[i] << ' '; } cout << endl; return; } for(int i=1;i<=n;i++){ if(!use[i]){ use[i]=1; num[now]=i; dfs(now+1); use[i]=0; } } }
int main(){ cin >> n; dfs(1); return 0; }
|
例2:n皇后问题
给定一个整数$n$,表示在$n*n$的棋盘上摆放$n$个皇后,保证每行,每列,每一斜线只有一个皇后,求所有的摆放方法
分析:类似上一题,每次摆放时判断当前点是否可以放,若放,标记行、列、斜线,进入下一行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #include<bits/stdc++.h> using namespace std;
const int N=20;
int n; char g[N][N]; bool col[N],dg[N],udg[N];
void dfs(int u){ if(u==n){ for(int i=0;i<n;i++){ cout << g[i] << endl; } cout << endl; } for(int i=0;i<n;i++){ if(!col[i]&&!dg[u+i]&&!udg[n-u+i]){ g[u][i]='Q'; col[i]=dg[u+i]=udg[n-u+i]=true; dfs(u+1); col[i]=dg[u+i]=udg[n-u+i]=false; g[u][i]='.'; } } }
int main(){ cin >> n; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ g[i][j]='.'; } } dfs(0); return 0; }
|
$BFS$:
每次扩展队列中的元素,若扩展后的点符合要求即入队,搜索到终点后或队列为空停止
例2:给定一个$n*m$的迷宫,其中$0$表示路,$1$表示墙,求从左上走到右下的最短长度

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include<bits/stdc++.h> using namespace std;
const int N=105; int n,m; int mp[N][N]; int d[N][N]; int dx[5]={0,0,0,-1,1},dy[5]={0,1,-1,0,0}; void bfs(){ memset(d,-1,sizeof d); d[1][1]=0; queue<pair<int,int>>q; q.push({1,1}); while(!q.empty()){ auto t=q.front(); q.pop(); int x=t.first,y=t.second; if(x==n&&y==m){ cout << d[x][y] << endl; break; } for(int i=1;i<=4;i++){ if(x+dx[i]>n||x+dx[i]<1||y+dy[i]>m||y+dy[i]<1)continue; if(mp[x+dx[i]][y+dy[i]])continue; if(d[x+dx[i]][y+dy[i]]==-1){ d[x+dx[i]][y+dy[i]]=d[x][y]+1; q.push({x+dx[i],y+dy[i]}); } } } }
int main(){ cin >> n >> m; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cin >> mp[i][j]; } } bfs(); return 0; }
|