什么是DFS?
深度优先遍历(DFS)也叫深度优先搜索。顾名思义,深度优先,则是以深度为准则,先一条路走到底,直到达到目标。这里称之为递归下去。 DFS相当与一种工具,回溯是深度优先搜索的一种。
简述实现步骤
1、从顶点出发。
2、访问顶点,也就是根节点。
3、依次从顶点的未被访问的邻接点出发,进行深度优先遍历;直至和顶点有路径相通的顶点都被访问。
4、若此时尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到所有顶点均被访问过为止。
什么是BFS?
BFS又叫广度优先搜索,是一种利用队列实现的搜索算法。简单来说,其搜索过程和 “湖面丢进一块石头激起层层涟漪” 类似。
即一层一层的搜索
DFS与BFS的区别
-
BFS 的重点在于队列,而 DFS 的重点在于递归。这是它们的本质区别。
-
BFS 常用于找单一的最短路线,它的特点是 “搜到就是最优解”,而 DFS 用于找所有解的问题,它的空间效率高,而且找到的不一定是最优解,必须记录并完成整个搜索,故一般情况下,深搜需要非常高效的剪枝。
应用举例
acwing 1113.红与黑
DFS
#include<iostream>
#include<cstring>
using namespace std;
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
const int N = 25;
char g[N][N]; //存图的
int st[N][N]; //标记这个点有没有被搜过
int n,m; //n行m列
int res;
void dfs(int x,int y)
{
st[x][y] = 1; //标记被遍历
for(int i=0; i<4; i++)
{
int a = x + dx[i], b = y + dy[i]; //邻接点的坐标
if(a<0 || a>=n || b<0 || b>=m) continue; //出界
if(st[a][b]) continue; //已经被访问过
if(g[a][b] != '.') continue; //遇到障碍
res++;
dfs(a,b);//不需要回溯
}
}
int main()
{
while(cin >> m >> n)
{
if(m==0 && n==0) break;
res = 1;
memset(st,0,sizeof st);
for(int i=0; i<n; i++) cin >> g[i];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(g[i][j] == '@')
{
dfs(i,j);
break;
}
cout << res << endl;
}
}
BFS
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
typedef pair<int,int> PII;
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
const int N = 25;
char g[N][N]; //存图的
int st[N][N]; //标记这个点有没有被搜过
int n,m; //n行m列
int res;
void bfs(int x,int y)
{
queue<PII> q;
q.push({x,y});
while(q.size() > 0) //队列不空
{
PII t = q.front(); //取出队头
q.pop();//出队
for(int i=0; i<4; i++) //遍历四个方向
{
int a = t.first + dx[i], b = t.second + dy[i]; //队头邻接点的坐标
if(a<0 || a>=n || b<0 || b>=m) continue; //出界
if(st[a][b] == 1) continue; //已经被访问过
if(g[a][b] != '.') continue; //遇到障碍
res++;
q.push({a,b});
st[a][b] = 1; //标记(a,b)已经被访问过
}
}
}
int main()
{
while(cin >> m >> n)
{
if(m==0 && n==0) break;
res = 1;
memset(st,0,sizeof st);
for(int i=0; i<n; i++) cin >> g[i];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(g[i][j] == '@')
{
bfs(i,j);
break;
}
cout << res << endl;
}
}