c++DFS和BFS的实现

DFS与BFS的实现

前言

DFS和BFS都是搜索的一种方式,两种不同的搜索方向对应着不同的情景,但无论怎么样,他们都是暴力搜索的思路,都能覆盖到全部的情况,下面讲简单的阐述一下他们应用的场合和实现的方式.

DFS

他叫什么?

深度优先搜索

主要的内容是什么?

如果把每一条路径分成好几层,但找到其中的一层时,他会选择寻找下一层的位置,而不是继续探索同一层的其他位置.

当需要寻找某两点之间的路径数的时候,就可以选择DFS

例题


P1605迷宫
题目描述

给定一个 N × M N \times M N×M 方格的迷宫,迷宫里有 T T T 处障碍,障碍处不可通过。

在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。

输入格式

第一行为三个正整数 N , M , T N,M,T N,M,T,分别表示迷宫的长宽和障碍总数。

第二行为四个正整数 S X , S Y , F X , F Y SX,SY,FX,FY SX,SY,FX,FY S X , S Y SX,SY SX,SY 代表起点坐标, F X , F Y FX,FY FX,FY 代表终点坐标。

接下来 T T T 行,每行两个正整数,表示障碍点的坐标。

输出格式

输出从起点坐标到终点坐标的方案总数。

样例 #1
样例输入 #1
2 2 1
1 1 2 2
1 2
样例输出 #1
1
提示

对于 100 % 100\% 100% 的数据, 1 ≤ N , M ≤ 5 1 \le N,M \le 5 1N,M5 1 ≤ T ≤ 10 1 \le T \le 10 1T10 1 ≤ S X , F X ≤ n 1 \le SX,FX \le n 1SX,FXn 1 ≤ S Y , F Y ≤ m 1 \le SY,FY \le m 1SY,FYm

思路

(最最最最典型的DFS)

可以使用一个方位数组,用for循环来实现位置的移动,最后只需要注意记录次数就行了

代码实现

#include<iostream>
using namespace std;
int map[11][11]={};
int begin1_x,begin1_y;
int end_x,end_y;
int n,m,t;
bool flag[11][11]={};
int sx[5]={0,1,-1,0,0};
int sy[5]={0,0,0,1,-1};
int sum=0;
void dfs(int begin_x,int begin_y)
{
    if(begin_x==end_x && begin_y==end_y)
    {
        sum++;
        return;
    }
    int now_x=0,now_y=0;
    flag[begin_x][begin_y]=1;
    for(int i=1;i<=4;i++)
    {
        now_x=begin_x+sx[i];
        now_y=begin_y+sy[i];
        if(now_x<1 || now_x>n || now_y<1 || now_y>m || map[now_x][now_y]==1 ||flag[now_x][now_y]==1) continue;
        flag[now_x][now_y]=1;
        dfs(now_x,now_y);
        flag[now_x][now_y]=0;
    }

}
int main()
{
    cin>>n>>m>>t;
    cin>>begin1_x>>begin1_y>>end_x>>end_y;
    for(int i=1;i<=t;i++)
    {
        int a,b;
        cin>>a>>b;
        map[a][b]=1;
    }
    dfs(begin1_x,begin1_y);
    cout<<sum<<endl;
    return 0;
}

BFS

他又叫什么?

深度优先搜索

主要的内容是什么?

在找到某个位置的时候,他会先记录下这个位置来接下来要走的地方,但是先放着,先去探索同一层的其他位置.在本层全部探索完毕之后,他才会走之前已经记录下来的位置.

例题


马的遍历
题目描述

有一个 n × m n \times m n×m 的棋盘,在某个点 ( x , y ) (x, y) (x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。

输入格式

输入只有一行四个整数,分别为 n , m , x , y n, m, x, y n,m,x,y

输出格式

一个 n × m n \times m n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 − 1 -1 1)。

样例 #1
样例输入 #1
3 3 1 1
样例输出 #1
0    3    2    
3    -1   1    
2    1    4
提示
数据规模与约定

对于全部的测试点,保证 1 ≤ x ≤ n ≤ 400 1 \leq x \leq n \leq 400 1xn400 1 ≤ y ≤ m ≤ 400 1 \leq y \leq m \leq 400 1ym400

思路

由于马的移动方式是已知的,所以用一个特殊的方位数组来定义马的移动即可.

代码实现

#include<iostream>
#include<queue>
#include<iomanip>
using namespace std;
const int maxn=401;
int map[maxn][maxn]={};
int n,m,x,y;
struct p
{
    int x,y;
};
int flag[maxn][maxn]={};

queue <p> q;
queue <p> q_copy;
int sx[9]={0,1,2,2,-1,-2,1,-2,-1};
int sy[9]={0,2,1,-1,2,1,-2,-1,-2};
void bfs(int times)
{
    if(q.empty()) return ;
    while(!q.empty())
    {
        p p1=q.front();
        q.pop();
        int x=p1.x;
        int y=p1.y;
        for(int i=1;i<=8;i++)
        {
            int now_x=x+sx[i];
            int now_y=y+sy[i];
            if(now_x<1 || now_x>n || now_y<1 || now_y>m || flag[now_x][now_y]!=0) continue;
            flag[now_x][now_y]=times;
            p p2;
            p2.x=now_x,p2.y=now_y;
            q_copy.push(p2);
        }
    }
    q.swap(q_copy);
    bfs(++times);
    
}
int main()
{
    
    cin>>n>>m>>x>>y;
    p P;
    P.x=x,P.y=y;
    q.push(P);
    flag[x][y]=-1;
    bfs(1);
    
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(flag[i][j]==0) flag[i][j]=-1;
        }
    }
    flag[x][y]=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cout<<left<<setw(4)<<flag[i][j];
        }
        cout<<endl;
    }
    return 0;
}

小结

  1. DFS和BFS都是搜索的一种方式,在有时是都都可以用的,在特殊的场合只能用其中一种,只需要我们根据题目的特点去进行选择即可.
  2. 在实现的时候经常会用到方位数组,判断数组,栈等.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值