浅谈bfs与dfs

  这几天刷了点bfs与dfs的题,来总结下, 

     上~~~~上图

       浅谈bfs与dfs_第1张图片

咳~咳~咳 错了。。。。。

好了,好了,咋也是正经人,进入主题

dfs

   dfs实叫深度优先搜索算法,起始它只是一种搜索的方法思路,并没有固定的算法格式,假设这样的情景,一个姑娘爱你爱的深沉,被你拒绝了好多次了,可就是不放弃你说“只要你没有结婚,我就有机会”,典型的不撞南墙不回头,一条道走到黑,这种。。。。对,就是这样的,dfs就是有着你追隔壁班女神的这样的执着,说到这里,继续上图。。。。

假设你穿越到古代的你娶了三位小妾,晚上让谁来侍寝苦恼了你好久,你需要一个他们侍寝的顺序

浅谈bfs与dfs_第2张图片                          浅谈bfs与dfs_第3张图片                                浅谈bfs与dfs_第4张图片

             1号小姐姐                              2号小姐姐                                       3号小姐姐

 浅谈bfs与dfs_第5张图片

跟随着红色箭头你就可以得到3位美妾的侍寝的所有可能的顺序了,我就问你你选哪种,我选三在最后一夜的,别问我为什么,就因为有句话叫先苦后甜~ 嘻嘻嘻。DFS的重要点在于状态回溯。代码如下

  

#include 
#include 
using namespace std;
int n;
const int N =8;
int path[N];
bool st[N];
void dfs(int x){
    if(x==n){
        for(int i=0;i>n;
    dfs(0);
    return 0;
}

 POJ 1321-棋盘问题

    在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

 input :   

2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

output: 2

            1

你会发现核心代码跟上述太大的没有区别,只是我们需要确定节点是“#”才可加入递归中去

#include 
#include 
#include 
using namespace std;
int n,k,l;
int flag;
const int N =10;
char g[N][N];
bool col[N];
void dfs(int x,int t){
    if(t==k){
      flag++;
      return ;
    }
    if(x==n) return ;
    //不摆放
    dfs(x+1,t);
    //摆放
    for(int i=0;i>g[i][j];
        }
         dfs(0,0);
         printf("%d\n",flag);
  }
  return 0;
}

      bfs

浅谈bfs与dfs_第6张图片

假设有如上图1这样的迷宫,0为可走,1为墙(别想狗急跳墙了哈),只有上下左右四个方向我们可以走,我们模拟下用bfs如何从左上角到达右下角的路径的,我们从(0,0)点出发,向周围扩展

只有(1,0),从(1,0)这个点再扩展到(2,0),(1,1)下次扩展只有(1,1)可以扩展,扩展到(1,2),从(1,2)就可扩展到(2,2)这时遍历完了。由于每次都是向周围扩展一次,最先到达的不就是我们需要的最短的路径了,这里需要借用数据结构了

int n = 10, m = 10;                   //地图宽高
void BFS()
{
    queue que;              //用队列来保存路口
    int graph[n][m];          //地图
    int px[] = {-1, 0, 1, 0};   //移动方向的数组
    int py[] = {0, -1, 0, 1};
    que.push(起点入队);      //将起点入队
    while (!que.empty()) {    //只要队列不为空
        auto temp = que.pop();          //得到队列中的元素
        for (int i = 0; i != 4; ++i) {
            if(//可以走) {
                //标记当前格子
                //将当前状态入队列,等待下次提取
            }
        }
    } 
}

bfs裸题,给定一个 n×m 的二维整数数组,用来表示一个迷宫,数组中只包含 00 或 11,其中 00 表示可以走的路,11 表示不可通过的墙壁。

最初,有一个人位于左上角 (1,1) 处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。

请问,该人从左上角移动至右下角 (n,m) 处,至少需要移动多少次。

#include 
#include 
#include 
using namespace std;
const int N = 100;
typedef pairPII;
int n,m;
int g[N][N];
int d[N][N];//记录到达这个点行走的路程,
PII h[N*N];//数组模拟的队列
int tx[4]={0,1,0,-1};
int  ty[4]={1,0,-1,0};
int bfs(){
    int hh=0,tt=0;
    memset(d,-1,sizeof(d));//初始为-1,也可以区别当前的节点有没有走过
    h[tt]={0,0};
    d[0][0]=0;
    while(tt>=hh){
        auto t=h[hh++];//出队
        for(int i=0;i<4;i++){
            int x=t.first+tx[i],y=t.second+ty[i];
            if(x>=0&&x=0&&y>n>>m;
    for(int i=0;i>g[i][j];
    cout<

 HDU2717CatchThatCow(BFS很容易理解的例题)

农夫约翰已被告知一头逃亡母牛的位置,并希望立即抓住她。他从数轴上的点N (0 ≤ N ≤ 100,000) 开始,而奶牛在同一数轴上的点K (0 ≤ K ≤ 100,000) 处。Farmer John 有两种交通方式:步行和传送。

* 行走:FJ 可以在一分钟内从X点移动到X - 1 或X + 1点
* 传送:FJ 可以在一分钟内从X点移动到 2 × X点。

如果母牛不知道它的追逐,根本不动,农夫约翰需要多长时间才能取回它?

input :5 17

output: 4

 Farmer John 到达逃亡母牛的最快方式是沿着以下路径移动:5-10-9-18-17,需要 4 分钟。

#include 
#include 
#include 
#include 
using namespace std;
struct node{
  int x,td;
};
const int N = 100010;
bool map[N];
int n,m;
bool check(int x){
  if(x<0||x>N||map[x])return false;
  return true;
}
int bfs(){
    queueq;
    node t={n,0};
    q.push(t);
    map[n]=true;
    while(q.size()){
      node temp=q.front();
      q.pop();
      if(temp.x==m)return temp.td;
      //状态转移
      if(check(temp.x-1)){
        node e={temp.x-1,temp.td+1};
        map[e.x]=true;
        q.push(e);
      }
      if(check(temp.x+1)){
        node e={temp.x+1,temp.td+1};
        map[e.x]=true;
        q.push(e);
      }
      if(check(temp.x*2)){
        node e = {temp.x*2,temp.td+1};
        map[e.x]=true;
        q.push(e);
      }
    }
}
int main(){
  while(~scanf("%d%d",&n,&m)){
    memset(map,false,sizeof(map));
    int ans=bfs();
    printf("%d\n",ans);
  }
}

3.总结

对于这两个搜索方法,其实我们是可以轻松的看出来,他们有许多差异与许多相同点的。

1.数据结构上的运用

DFS用递归的形式,用到了栈结构,先进后出。

BFS选取状态用队列的形式,先进先出。

2.复杂度

DFS的复杂度与BFS的复杂度大体一致,不同之处在于遍历的方式与对于问题的解决出发点不同,DFS适合目标明确,而BFS适合大范围的寻找。

3.思想

思想上来说这两种方法都是穷竭列举所有的情况。

                  喔噻,看到这里了,可惜没有图可以上了,不然奖励奖励,哈哈哈

你可能感兴趣的:(算法,算法,c语言,数据结构)