热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

bfs与dfs

从大一就开始搞算法,结果到现在对这些的理解都还这么浅。。。dfs(深度优先搜索):这种算法最形象的描述就是不撞南墙不回头,不达到目的就一直往一个方向搜,实现算法使用的是递归,每到一

从大一就开始搞算法,结果到现在对这些的理解都还这么浅。。。

dfs(深度优先搜索):这种算法最形象的描述就是不撞南墙不回头,不达到目的就一直往一个方向搜,实现算法使用的是递归,每到一个新的点就会有一些信息被更新,将这些更新后的信息作为参数传入下一层,如果一个方向的深搜出口不符合条件那么就回溯到上一个点,并且上一个点的信息仍然没有改变.,总结一下就是搜索深度优先,能深就不回去

bfs(广度优先搜索):就和dfs是反着的,利用队列来实现,bfs优先搜索广度,就是把一个点的能到的所有点先确定了后再向深度进行搜索。

我们拿一个图来说明

如果用dfs来走,那么就像这样

这就是用dfs搜索的一条路径,可以看出,如果走一条路要用1分钟的话,那么用dfs走到终点的路径不一定是时间最短的。

1 void dfs(当前点)
2 {
3 if(达到条件) //递归出口
4 return ;
5 通过某种方法从当前点到下一个点tmp;
6 dfs(tmp);
7 }

 

再看看bfs

其中颜色相同的线表示他们所指目的地是同时检测的,当然我这里只画了左边的一半。这种情况下我们到达终点还是不能确保时间最短(但是如果利用优先队列就可以)。

void bfs(int start)
{
queueq;
q.push(start);vis[start]=1;//vis一般记录一下某个点有没有访问过,比如如果终点访问到了就结束,或者一个点访问了就不用访问
while(!q.empty())
{
int s=q.front();q.pop();
通过某种方式到下一个点next;
if(!vis[next])
{
q.push(next);
}
如果到达终点就结束
}
}

dfs和bfs我的理解还是不深,有时候不能搞清楚用哪个,因为有些时候两个用都可以,但有时候却只能用其中一个,或者其中一个简单,另一个十分复杂。

例题:poj3126,迷宫问题

dfs和bfs都可以找到起点到终点的路径,但只能找到存在性,如果有要求最优解那么就还要利用优先队列。

优先队列的bfs:顾名思义,就是在实现bfs的过程中用的是优先队列,优先队列可以对其中存储的结构的某些值进行自动的排序,依靠这个特点,在上面的例子中,我们可以拿结构体存每个点的信息(起点到这个点的时间和这个点的编号),存入优先队列时按照‘时间’从小到大,这样每次取出的第一个点到起点的时间都最短,如果这个点可以到终点,那么这个时间就是答案。

例题:poj2312 +代码

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mod (1000000000+7)
#define maxn 2000+10
#define SIZE 400
#define lson rt<<1
#define rson rt<<1|1
#define midd (l+r)>>1
#define lowbit(x) (x&(-x))
typedef long long ll;
const int inf_max = 0x3f3f3f3f;
const int inf_min = 0xc0c0c0c0;
const double eps=1e-5;
using namespace std;
string pr[2]={"No\n","Yes\n"};
int dir[][2]={1,0,-1,0,0,1,0,-1};
int n,m,vis[SIZE][SIZE];
char mp[SIZE][SIZE];
struct Point
{
int x,y,t;
friend bool operator<(Point a,Point b)
{
return a.t>b.t;
}
friend bool operator== (Point a,Point b)
{
return (a.x==b.x)&&(a.y==b.y);
}
}start,fina;
void BFS()
{
priority_queue

q;
vis[start.x][start.y]=1;
q.push(start);
while(!q.empty())
{
Point next,now;
now=q.top();q.pop();
for(int i=0;i<4;i++)
{
next.x=now.x+dir[i][0];next.y=now.y+dir[i][1];
if(next.x>=1&&next.x<=n&&next.y>=1&&next.y<=m&&!vis[next.x][next.y]&&mp[next.x][next.y]!='R'&&mp[next.x][next.y]!='S')
{
int t1=1;
if(mp[next.x][next.y]=='B')
t1++;
vis[next.x][next.y]=1;
next.t=now.t+t1;
q.push(next);
if(next==fina)
{
printf("%d\n",next.t);
return ;
}
}
}
}
printf("-1\n");
return ;
}
int main()
{
while(scanf("%d%d",&n,&m)&&(m+n))
{
memset(vis,0,sizeof(vis));
memset(mp,0,sizeof(mp));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>mp[i][j];
if(mp[i][j]=='Y')
{
start.x=i;
start.y=j;
}
if(mp[i][j]=='T')
{
fina.x=i;fina.y=j;
}
}
BFS();
}
return 0;
}

 



推荐阅读
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文介绍了最长上升子序列问题的一个变种解法,通过记录拐点的位置,将问题拆分为左右两个LIS问题。详细讲解了算法的实现过程,并给出了相应的代码。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 本文介绍了一道网络流题目hdu4888 Redraw Beautiful Drawings的解题思路。题目要求以行和列作为结点建图,并通过最大流算法判断是否有解以及是否唯一。文章详细介绍了建图和算法的过程,并强调在dfs过程中要进行回溯。 ... [详细]
  • Learning to Paint with Model-based Deep Reinforcement Learning
    本文介绍了一种基于模型的深度强化学习方法,通过结合神经渲染器,教机器像人类画家一样进行绘画。该方法能够生成笔画的坐标点、半径、透明度、颜色值等,以生成类似于给定目标图像的绘画。文章还讨论了该方法面临的挑战,包括绘制纹理丰富的图像等。通过对比实验的结果,作者证明了基于模型的深度强化学习方法相对于基于模型的DDPG和模型无关的DDPG方法的优势。该研究对于深度强化学习在绘画领域的应用具有重要意义。 ... [详细]
  • macOS Big Sur全新设计大版本更新,10+个值得关注的新功能
    本文介绍了Apple发布的新一代操作系统macOS Big Sur,该系统采用全新的界面设计,包括图标、应用界面、程序坞和菜单栏等方面的变化。新系统还增加了通知中心、桌面小组件、强化的Safari浏览器以及隐私保护等多项功能。文章指出,macOS Big Sur的设计与iPadOS越来越接近,结合了去年iPadOS对鼠标的完善等功能。 ... [详细]
author-avatar
龙井龙井2502908921
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有