深搜与广搜

DFS(深度优先搜索)

从起点出发,朝任一个可能的方向走,走过的点要做标记,一直向前走。若走不了了,就回退一步,从这一个状态走向没有走过的另一个方向。

之所以称为深度优先搜索,因为它是朝着一个方向一直走到底,以深度优先,然后回溯。

DFS一般用的是递归的方法。

迷宫问题

给一个迷宫,0表示道路,1表示墙壁,找出一条从左上角到右下角的最短路径

首先建立一个next[4][2]数组,表示下一步要走的方向,自定义方向的优先级,本题是从左上到右下,

那么,我可以按照下,右,上,左的顺序,则next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

遍历四个方向的代码为

for(int i=0;i<4;i++)
    tx=x+next[i][0];ty=y+next[i][1];//x,y为当前位置坐标,tx,ty为下一步要走的坐标

或者建立两个一维数组int nx[4]={0,1,0,-1},ny={1,0,-1,0};for(int i=0;i<4;i++)    {        int tx=x+nx[i],ty=y+ny[i];    }

还需要建立一个bool类型的vis[maxn][maxn]数组,来判断是否已经走过这条路

int nx[4]={0,1,0,-1},ny={1,0,-1,0};
void judge(int x,int y)//判断是否越界和是否已经走过
{
    return x>=0&&y>=0&&x<=n&&y<=m&&v[x][y]==0;//n为行数,m为列数
}
void dfs(int x,int y,int step)
{
    if(x==end1&&y==end2)//到达终点
    {
        ans=min(ans,step);
        return;
    }
    v[x][y]=1;//标记为走过
    for(int i=0;i<4;i++)
    {
        int tx=x+nx[i],ty=y+ny[i];
        if(judge(tx,ty))
        {
            dfs(tx,ty,step+1);//更新步数
        }
    }
    v[x][y]=0;//回退时,清除标记,
}

  给出n个正整数a1,a2....an,和一个正整数k,问是否能从这n个数中选取若干个,使其和为k

int ans=0,a[N],b[N],sum=0,step=0;//ans表示有几种情况,step代表每种情况需要几个数使其和为k
void dfs(int i,int sum,int step)
{
    if(i==n+1)//当i等于n时,因为又递归了一次,所以要判断是否等于n+1,注意只有在n个数全部都枚举完了再判断sum是否等于k
    {
        if(sum==k)
        {
            ans++;
            b[ans]=step;
        }
        return;
    }
    dfs(i+1,sum+a[i],step+1);//加上a[i]的情况,数量加1
    dfs(i+1,sum,step);//不加a[i]的情况
}

因为DFS采用递归的方法,所以很费时间,如果不剪枝的话,是很难AC的;

最简单的剪枝是sum>k时,直接返回

BFS(广度优先搜索),是一种利用队列(用队列来保存未访问的结点,先进先出)实现的搜索算法。简单来说,其搜索过程和 “湖面丢进一块石头激起层层涟漪” 、“树的层次遍历”类似。从源顶点s出发,依照层次结构,逐层访问其他结点。即访问到距离顶点s为k的所有节点之后,才会继续访问距离为k+1的其他结点。

bfs是按状态的层次进行扩展的,所以第一次访问到的终点节点所需步数,一定为最小步数

void bfs(初始状态)
{
 新建队列q;
 初始状态入队;
 while(队列为空)
 {
  取出队首状态;出队;
  if(到达目标状态) {跳出循环;}
  for(遍历下一层状态)
  {
   if(该状态未被访问) 入队;
   ...
  }
 }

struct node
{
    int x,y,dis;
    node(int a,int b,int c):x(a),y(b),dis(c){}
}start;
int bfs(node start)
{
    bool v[siz][siz]={0};
    queue<node>q;
    q.push(start);
    v[start.x][start.y]=1;
    while(!q.empty())
    {
        node now=q.front();
        q.pop();
        if(now.x==endx&&now.y=endy)
            return now.dis;
        for(int i=0;i<4;i++)
        {
            int tx=now.x+dx[i],ty=now.y+dy[i];
            if(can-move(tx,ty))
            {
                v[tx][ty]=1;
                node newnode(tx,ty,dis+1);
                q.push(newnode);
            }
        }
    }
    return -1;
}

原文地址:https://www.cnblogs.com/175426-hzau-zxjc-con/p/9382291.html

时间: 2024-08-01 00:16:52

深搜与广搜的相关文章

看数据结构写代码(39) 图的遍历(深搜和广搜)

图的遍历算法 有两种 :深度优先搜索遍历 和 广度 优先搜索遍历.深度优先搜索遍历类似与 树的 先序遍历.广度优先搜索遍历类似与树的层序遍历.只不过 图 可以有 不连通的 节点,所以 得 遍历 整个顶点数组. 深搜遍历 总是 先访问当前节点的邻接点,而 广搜算法 是 先访问顶点的邻接点 要 先于 后访问顶点的邻接点 被 访问. 具体遍历顺序如下: 以下代码 以 图的 邻接多重表 为 基本结构进行 遍历. 首先更改 上节 的 查找 邻接点 和 下一个邻接点的 返回值,以及 邻接点的 代码 有误,少

深搜和广搜的原理及优缺点

原文来源:https://blog.csdn.net/dark_cy/article/details/88926435 深搜原理深搜,顾名思义,是深入其中.直取结果的一种搜索方法. 如果深搜是一个人,那么他的性格一定倔得像头牛!他从一点出发去旅游,只朝着一个方向走,除非路断了,他绝不改变方向!除非四个方向全都不通或遇到终点,他绝不后退一步!因此,他的姐姐广搜总是嘲笑他,说他是个一根筋.不撞南墙不回头的家伙. 深搜很讨厌他姐姐的嘲笑,但又不想跟自己的亲姐姐闹矛盾,于是他决定给姐姐讲述自己旅途中的经

宽搜和广搜、

广搜与深搜的小区别 一般来说,广搜常用于找单一的最短路线,或者是规模小的路径搜索,它的特点是"搜到就是最优解", 而深搜用于找多个解或者是"步数已知(好比3步就必需达到前提)"的标题,它的空间效率高,然则找到的不必定是最优解,必需记实并完成全数搜索,故一般情况下,深搜需要很是高效的剪枝(优化). 像搜索最短路径这些的很显著若是用广搜,因为广搜的特征就是一层一层往下搜的,保证当前搜到的都是最优解,当然,最短路径只是一方面的操作,像什么起码状态转换也是可以操作的.深搜就

最短路问题------分别用深搜和广搜去解题

最少步数 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 这有一个迷宫,有0~8行和0~8列: 1,1,1,1,1,1,1,1,1 1,0,0,1,0,0,1,0,1 1,0,0,1,1,0,0,0,1 1,0,1,0,1,1,0,1,1 1,0,0,0,0,1,0,0,1 1,1,0,1,0,1,0,0,1 1,1,0,1,0,1,0,0,1 1,1,0,1,0,0,0,0,1 1,1,1,1,1,1,1,1,1 0表示道路,1表示墙. 现在输入一个道路的坐标作为起点

深搜和广搜

先说说这个神秘的深搜: 前几天我心中的大牛给我讲了深搜感觉还是挺简单的,可大牛告诉我深搜深搜深的让你不知道怎么搜 我们也是从一道题来看:n的全排列 比如说3的全排列 123 213 321 这就是全排列   在没学过深搜的时候我们会用for循环来做这道题 但是如果n很大的时候就不行了 所以我们就一定要深搜了 其实在我看来深搜和递归是亲兄弟 深搜就是递归的加强版 我先写一个简单的dfs(深搜)函数的代码 #include<stdio.h> int dfs(int x) { if(x > n

深搜 ,广搜,队列 nyoj 27 水池数目

水池数目 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地图上仅标识了此处是否是水池,现在,你的任务来了,请用计算机算出该地图中共有几个水池. 输入 第一行输入一个整数N,表示共有N组测试数据 每一组数据都是先输入该地图的行数m(0<m<100)与列数n(0<n<100),然后,输入接下来的m行每行输入n个数,表示此处有水还是没水(1表示此处是水

树的深搜和广搜

树的深搜: 树的重心 思路:我们可以遍历每一个节点,获取当前节点除外以后的每一个连通块中的点的数量,用一个res变量存储,每次到最后的时候用一个ans存储res中的最小值. 1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 5 using namespace std; 6 7 const int N = 1e5+10; 8 9 int e[2 * N], ne[2 * N], h[N]

算法学习笔记 二叉树和图遍历—深搜 DFS 与广搜 BFS

图的深搜与广搜 马上又要秋招了,赶紧复习下基础知识.这里复习下二叉树.图的深搜与广搜.从图的遍历说起,图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其经典应用走迷宫.N皇后.二叉树遍历等.遍历即按某种顺序访问"图"中所有的节点,顺序分为: 深度优先(优先往深处走),用的数据结构是栈, 主要是递归实现: 广度优先(优先走最近的),用的数据结构是队列,主要是迭代实现: 对于深搜,由于递归往往可以方便的利

算法学习笔记(六) 二叉树和图遍历—深搜 DFS 与广搜 BFS

图的深搜与广搜 复习下二叉树.图的深搜与广搜. 从图的遍历说起.图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其经典应用走迷宫.N皇后.二叉树遍历等.遍历即按某种顺序訪问"图"中全部的节点,顺序分为: 深度优先(优先往深处走),用的数据结构是栈, 主要是递归实现. 广度优先(优先走近期的).用的数据结构是队列.主要是迭代实现. 对于深搜.因为递归往往能够方便的利用系统栈,不须要自己维护栈.所以通常实