其实我真的还不是很懂DFS和BFS,虽然感觉原理上理解了,可用它做题的时候总会被一些奇奇怪怪的东西卡住。。。。。。
于是做了一个大胆的决定,我来试试一边整理一边学习一边写博客来学习这两个个神奇的东东。。。。。。QwQ
所以这两篇博客可能会写很久很久。。。。。。也很可能没有逻辑没有条理。。。。。。嗯,反正只有我自己看,看的懂就好,应该没事吧。。。。。。QwQ
现在先开始写有关DFS的一些理解

1.DFS的用法

DFS的意思是深度优先搜索,它是一种遍历或搜索树或图的算法。总感觉只用语言来描述这个算法的思想太过繁杂难懂了,所以我在这里用图的方式,主要目的是理解DFS的用法,可能有些在定义上不准确的地方,不过个人感觉思想和用法才是最关键的部分。
所以让我们来先看看图:

这是一个简单的树状图,我们现在利用这个图来出一道题目:
现在我们从v1出发,走到v10,那么一共有多少条合法路径可以到达v10?
现在我们开始用DFS的思想开始对这个过程进行模拟。
我们先让节点由v1 -> v2,然后v2 -> v4

就像这样,绿色代表我们已经搜索过的路径。当我们到v4时,我们发现已经没有更深的路了,而且v4 != v10,所以这条路是死路,我们就返回到v2寻找,就会发现还有条路,v2 -> v5,v5 -> v8。

我们把已经“废掉”的路标记为黑色,开始搜索新发现的路径,直到v8发现路又没了,而且v8 != v10,于是我们返回到v5,把v8标记为黑色,再找新的路。

这时发现,我们从v5 -> v9 -> v10这条路是可行的,于是我们找到了一条真确的路,我们把真确的路标记成黄色,然后让可行路总数加一,然后再返回v1,对v1连接的另一个点进行同样的道路搜查,最后会发现三条可行的路。

这就是最简单的DFS问题,对一条一条路进行遍历,可行就返回真值,不可行就返回上一节点搜查,直至把整个树或图搜索完。

2.题目列举

对算法的理解,一般是要题目辅助的,接下我会给出一些例题,来更深一步的理解DFS的用法。

<1> 8皇后问题

一个8 * 8的棋盘,我们现在要在上面摆上8个皇后,要求它们不会把对方吃掉(即不在同一行,同一列,也不在45度对角线上),那么我们一共有多少种方法来摆放棋子呢?
这是一个很经典的DFS问题,对于这一问题,我觉得主要的难点是在理解DFS后,你应该怎么把这个问题转换成一个树或者图(这也是我一直做的不好的地方),转换成功后,你应该就可以很轻松的解决这个问题了。

#include<bits/stdc++.h>
using namespace std;int sum = 0;
const int N = 20;
int a[N];bool found(int i,int k)   //用于判断在此行放置皇后的当时位置
{            //的列和对角线上是否有皇后int j = 1;while(j < i){if(a[j] == k||abs(j - i) == abs(a[j] - k)) //a[j]和k为列return 0;                             //对角线用坐标差来表示j ++;}return 1;
}void dfs(int k)
{int i;if(k > 8)    //判断是否到达终点,若到达,可行总数加一sum ++;else    //没到达,继续循环{for(i = 1; i <= 8; i ++){if(found(k, i)){a[k] = i;      //k为当前所在行,a[k]表示所在列dfs(k + 1);   //进入下一行搜索}}}
}int main(void)
{dfs(1);cout << sum << endl;return 0;
}

简单理解它的思想,把棋盘转换成有8个“头”的树,每个“头”又连接着8个节点,然后每个节点又连接着8个子节点。。。。。。
用这样的方法,生成一个巨大的树,在满足条件的前提下,只要到树的最根部,最算是完成了一次合法路径的寻找。
用这样的算法来解决8皇后问题,它所用的标记方法是直接利用图来标记,(感觉自己一直不太对这玩意感冒,虽然知道是那么个东西,但总是换道题就废了。。。)其实,也可以利用vis[ ]数组来进行标记,只要理解了核心算法后,另一种标记方式的代码也就可以轻松打出了,在这就不例举了,我们来直接看下一道例题,我会用vis[ ]标记的方式来完成这道题。

<2>棋盘问题

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

输入:
有多组输入,每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n

当为-1 -1时表示输入结束。

随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。

输出:
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
这也是一道很经典的用DFS算法完成的题目,与DFS的核心思想十分贴近

#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;int sum, vis[20][20];
char a[20][20];
int n, m;void dfs(int k, int dis)     //k代表行数,dis代表棋子数
{if(dis == 0)            //如果棋子为0,找到一条合法路径sum ++;else{for(int i = k; i < n; i ++)     //从第k行,开始向下遍历合法路径{for(int j = 0; j < n; j ++){if(a[i][j] == '.'||vis[i][j])  //判断continue;          //若为空点或已经走过,跳过该点else{vis[i][j] = 1;dfs(k + 1, dis - 1);  //放一颗棋子,从下一行开始遍历vis[i][j] = 0;}}}}
}int main()
{while(cin >> n >> m){if(n == -1&&m == -1)break;for(int i = 0; i < n; i ++){getchar();          //因为是字符的输入,不用了话会输进回车    for(int j = 0; j < n; j ++){cin >> a[i][j];}}sum = 0; //初始化sum为0memset(vis, 0, sizeof(vis));  //初始化vis[ ]为0dfs(0, m);cout << sum << endl;}return 0;
}

其实这一题的思想和上一题基本相同,也是吧棋盘转化为树,然后利用DFS的思想对数进行遍历,就可以得出答案。
最后一点,应为DFS的遍历是一条枝干一条枝干进行的,其时间复杂度最坏的情为O(!n),所以,用上面的办法是无法对太大的树进行索查的,在难的题目中,我们往往会用的各种神奇的剪枝的操作。(虽然我没遇到过,我也不会。。。)所以,上面写的题目和思想,真的是DFS用法中的基础,革命的道路还在十分的漫长。。。。。。

关于DFS的一些拙劣的理解相关推荐

  1. 图的dfs非递归_如何理解恶心的递归

    力扣​leetcode-cn.com 递归恶心主要恶心在无论是做题还是解析都比较抽象,这里记录一下递归小白的理解过程: # Definition for a binary tree node. 以上图 ...

  2. 持续理解DFS(深度优先搜索)

    目录方便大家浏览: 博客的目的: 对DFS的概念理解: DFS的用途: 需要用到DFS的例题(来自力扣): DFS在树中的一些应用: DFS在数组中的一些应用: Last 博客的目的: 博主最近在刷有 ...

  3. 实现DFS之“油田”

    油田"问题是一个比较经典的体现DFS思想的题目,经过学习,对DFS也有了一点理解,下面介绍下这个题目~ 题目来源: Mid-Central USA 1997,ZOJ1709,POJ1562 ...

  4. The problem of maze(经典迷宫问题) DFS版

    又是这个题,上学期看过,但当时没能力自己写下来,只是把别人的代码认真的看了一遍.今天,终于自己把它给弄出来了.嘿嘿,经过自己思考的才能真正成为自己的东西.把这题做出来,可以说把DFS最基本的东西理解了 ...

  5. 递归求全排列的学习与理解

    递归求全排列 全排列: 从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列.当m=n时所有的排列情况叫全排列. 例题: 输出自然数 1 到n所有 ...

  6. DFS和BFS概念及实践+acwing 842 排列数字(dfs) +acwing 844. 走迷宫(bfs)

    DFS (深搜), 也有说就是递归的 执着: 一直搜到底,然后回溯下一个节点 数据结构 : stack (这里的栈,实际上是编译器内部的栈, 所以说也可以看成递归, 递归内部也是调用编译器内部栈) 空 ...

  7. 蓝桥杯15届第九题——垒骰子(dfs、动态规划、矩阵)

    前言:该题很值得研究,为什么这么说呢? 题目考查了较多方面的知识点,相信如果将这道题完全理解的话,我们对考查的知识点应用起来会更加得心应手. 下面我会通过三种方式将题目解析透彻,从浅入深. 垒骰子题目 ...

  8. 图图的存储、BFS、DFS(听说叠词很可爱)

    1. 基本概念 图的基本概念中我们需要掌握的有这么几个概念:无向图.有向图.带权图:顶点(vertex):边(edge):度(degree).出度.入度.下面我们就从无向图开始讲解这几个概念. 如图所 ...

  9. 洛谷 - P3975 [TJOI2015]弦论(后缀自动机)

    题目链接:点击查看 题目大意:给出一个字符串 s,再给出一次询问,询问分为两种类型: 0 k:如果不同位置的相同子串算作一个,求第 k 小的子串 1 k:如果不同位置的相同子串算作多个,求第 k 小的 ...

最新文章

  1. 部署通用基础设施, 满足顶级 SLA 要求
  2. duilib 显示内存图片
  3. 机器学习-特征工程中的样本不均衡处理方法
  4. 怎么把cad做的图分享给别人_在线协同文档分享后,别人只能看却不能写怎么办?...
  5. ApiBoot - ApiBoot Swagger 使用文档
  6. 【求助】如何从 Spark 的 DataFrame 中取出具体某一行?我自己的一些思考
  7. Codeforces Round #264 (Div. 2) 解题报告
  8. ra8873 ST7789区别
  9. 什么是设计思维Design Thinking——风靡全球的创造力培养方法
  10. ios申请企业开发者账号的代理_苹果企业开发者账号的申请详解
  11. web buuctf [0CTF 2016]piapiapia
  12. C - Fewest Flops
  13. 2020厦门国际银行数创金融杯建模大赛(一)----赛题说明数据重塑Baseline
  14. 开放原子训练营(第一季)铜锁探密,SM3杂凑算法加强至pro版
  15. 敏涵·精致遮暇乳打造“新国妆”专场 致力新锐品牌强势“出圈”
  16. HTML图片和多行文字并列显示
  17. 扫描普通二维码进入小程序
  18. PHP开发环境配置(PhpStudy ,PhpStorm)
  19. JDK 8 List集合使用记录
  20. DL/T 645多功能电能表通信协议测试方法

热门文章

  1. Django简单全文搜索(Django实现搜索功能)
  2. 陕西西安移动宽带配置图
  3. 易经与计算机科学,电子计算机与《易经》有啥关系
  4. 方便的邮箱密码登录邮箱方式分享
  5. input使用自动输入autofill的时候,修改背景颜色
  6. 今年冬天有点冷(1)
  7. 从苏宁电器到卡巴斯基(第二部)第13篇:我在卡巴的日子 XIII
  8. 生态赋能促进产业升级 CDEC中国数字智能生态大会聚焦生态变革
  9. 关于exists的理解(一)
  10. 手工制作Wav文件以及生成播放数据