dfs和bfs的简单总结
首先是dfs,又名深度优先搜索。看名字就知道,它的核心思想就是一直搜索,先在一条路上面一路撸到底,如果到底没有办法前进了,那么判断是否到达终点,如果没有到达,那么就回溯到之前的点再撸。
dfs的要点:
1、考虑当下应该怎么做,在你现在的点上面你应该怎么做,可以怎么做。可以向上吗?可以向下吗?
2、后面的和前面一样的做。递归的思想。
3、要考虑边界,终点等题目给出的条件检测。过滤掉那些不需要的解。
4、利用适当的数据结构,保存当前点是否走过,保存走过的路线等。
模版:
void dfs(int step)
{
判断你的所有条件,如果不行直接return;
for(循环每一个方向)
{
dfs(step+1)
}
return;
}
map【】【】记录走过的地方,走过的记为1
可以尝试利用堆栈来存放记录
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<iostream> using namespace std; int result[];
int book[];
int r=;
/*求九个不同的个位数组合满足,3位+3位=3位的题目,主要是记录一下dfs的模版*/
void dfs(int step)
{
if(step == )/*简单的优化一下*/
{
int sum = result[]* + result[]* + result[]* + result[]* + result[] + result[]; if(book[sum%] == )
return; sum/=; if(book[sum%] == )
return; sum/=;
if(book[sum%] == )
return;
} if(step == )
{
if(result[]* + result[]* + result[]* + result[]* + result[] + result[] == result[]* + result[]* + result[])
{
printf("%d%d%d + %d%d%d = %d%d%d\n",result[],result[],result[],result[],result[],result[],result[],result[],result[]);
r++;
}
return;
} int i;
for (i = ; i <= ; i++)
{
if(book[i] == )
{
result[step] = i;
book[i] = ;
dfs(step+);
book[i] = ;
}
} return;
} int main()
{
clock_t start,finish;
double duration;
start = clock(); dfs();
cout<<"-------------------"<<r<<endl; finish = clock();
duration = double(finish - start)/CLOCKS_PER_SEC;
printf("time used:%f ms\n\n",*duration);
return ;
}
接下来是bfs,又名广度优先搜索,他是一个老实人,一步步走的很踏实,只有把n步的能走的地方走遍,才会走第n+1步,慢慢的拓展
要点:
1、用队列保存每一步走的结果,用一个字段去表示走的步数;
2、没有递归,利用while循环到最终结果;
3、时刻注意队列的首尾指针的位置;
模版:
while(head<tail)
{
for(循环所有方向)
{
把坐标进行改变,改成now的坐标,意思就是走一步
判断所有不可能的情况,不可能就continue
标记走过了
在队列中加入这个走过的点和步数
*****tail++*****
}
*****head++*****
}
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<iostream> using namespace std; /*首先定义方向数组*/ /*
X/Y 0/-1
-1/0 0/0 1/0
0/1
右下左上*/ int way[][] = {
{,},//右
{,},//下
{-,},//左
{,-}//上
};
int map[][];
int book[][];
int n,m;
int head=;
int tail=;
int flag=; struct que
{
int x;
int y;
int stpe;
}; struct que q[]; int main()
{ int x,y;
cin>>n>>m;
for (int i = ; i <= n; i++)
{
for (int j = ; j <= m; j++)
{
cin>>map[i][j];
}
} head = ;
tail = ; q[tail].x = ;
q[tail].y = ;
q[tail].stpe = ;
tail++; book[][] = ;
flag = ; while (head<tail)
{
for (int i = ; i < ; i++)
{
x = q[head].x + way[i][];
y = q[head].y + way[i][]; if(x< || y < || x > n || y > m)
continue;
if(map[x][y] == && book[x][y] == )
{
q[tail].x = x;
q[tail].y = y;
q[tail].stpe = q[head].stpe + ;
tail++;
book[x][y] = ; } if(x == && y == )
{
printf("--------------------%d\n",q[tail-].stpe);
return ;
}
}
head++;
} return ;
}
主要是记录一下两钟搜索的模版,具体两种搜索的使用还要在实际中进行检验,对于迷宫的题目只是现在肯定不会迷茫了,之后对于图的遍历还有别的,对于两种搜索的比较取舍,之后再写吧。
dfs和bfs的简单总结的更多相关文章
- DFS与BFS——理解简单搜索(中文伪代码+例题)
新的方法和概念,常常比解决问题本身更重要. ————华罗庚 引子 深度优先搜索(Deep First Search) 广度优先搜索(Breath First Search) 当菜鸟们(比如我)初步接触 ...
- DFS与BFS题解:[kaungbin]带你飞 简单搜索 解题报告
DFS and BFS 在解题前我们还是大致讲一下dfs与bfs的.(我感觉我不会bfs) 1.DFS dfs(深度优先算法) 正如其名,dfs是相当的深度,不走到最深处绝不回头的那种. 深度优先搜 ...
- 图论中DFS与BFS的区别、用法、详解…
DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...
- 图论中DFS与BFS的区别、用法、详解?
DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...
- dfs和bfs的区别
详见转载博客:https://www.cnblogs.com/wzl19981116/p/9397203.html 1.dfs(深度优先搜索)是两个搜索中先理解并使用的,其实就是暴力把所有的路径都搜索 ...
- lightoj 1111 - Best Picnic Ever(dfs or bfs)
题目链接 http://www.lightoj.com/volume_showproblem.php?problem=1111 题意:给你一个有向图再给你几个人的位置,问所有人可以在哪些点相聚. 简单 ...
- [转帖]dfs和bfs
dfs和bfs https://www.cnblogs.com/wzl19981116/p/9397203.html 1.dfs(深度优先搜索)是两个搜索中先理解并使用的,其实就是暴力把所有的路径都搜 ...
- 图的DFS与BFS遍历
一.图的基本概念 1.邻接点:对于无向图无v1 与v2之间有一条弧,则称v1与v2互为邻接点:对于有向图而言<v1,v2>代表有一条从v1到v2的弧,则称v2为v1的邻接点. 2.度:就是 ...
- 二叉树 - DFS与BFS
二叉树 - DFS与BFS 深度优先遍历 (DFS Depth First Search) 就是一个节点不到头(叶子节点为空) 不回头 广度有点遍历(BFS Breadth First Sea ...
随机推荐
- 笔记一:OOAD与UML
一.面向对象的概念与方法 1. 面向对象 1.1. 面向对象是一种系统建模技术 1.2. 面向对象编程是按照OO的方法学来开发程序的过程 1.3. 通过分析系统内对象的交互来描述或建模一个系统 1. ...
- 使用计算监控(Using computed observables)
计算监控(Computed Observables) 如果有两个监控属性firstName, lastName,此时我们要显示full name,我们要怎么办呢? 这时,可以创建一个computed ...
- log4j2配置MDC分线程写日志
1.MDC是一个高级一些的工具,可以配置分用户(userid)写日志,也可以分线程 2.方法和道理都是相似的,在写入日志之前配置线程名或者用户id 3.如果将线程名配置为目录,可以将不同线程的日志输送 ...
- HDU3371--Connect the Cities(最小生成树)
Problem Description In 2100, since the sea level rise, most of the cities disappear. Though some sur ...
- 把excel数据导入mysql中
适用:每列的数据都不是以逗号分隔. 1.在mysql建表,全部字段与表头相同且顺序一致 2.将excel另存为csv格式,用Editplus把CSV文件另存为UTF-8编码格式 3.执行load da ...
- VBS调用系统API
如Beep的API声明为 Public Declare Function Beep Lib “kernel32″ Alias “Beep” (ByVal dwFreq As Long, ByVal d ...
- linux脚本Shell之awk详解
一.基本介绍1.awk: awk是一个强大的文本分析工具,在对文本文件的处理以及生成报表,awk是无可替代的.awk认为文本文件都是结构化的,它将每一个输入行定义为一个记录,行中的每个字符串定义为一个 ...
- glusterfs——volume管理
Q: 常用的命令有哪些? 创建volume: gluster volume create NAME stripe SCOUNT replica RCOUNT transport TYPE BRICK ...
- Broken Keyboard(悲剧文本)
你有一个键盘,键盘上所有的键都能正常使用,只是Home键和End键有时会自动按下.你并不知道这一情况,而是专心地打稿子,甚至连显示器都没开电源.当你打开显示器之后,展现在你面前的是一段悲剧文本.你的任 ...
- LeetCode OJ 220.Contains Duplicate 3
Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...