简谈DFS
所谓DFS就是“不撞南墙不回头”的一种搜索。其时间复杂度为O(V+E)。
能算出从起点到终点的全部路径,在算法执行的过程中需要一个visit[vi]数组来维护每个结点的访问情况,这样就能避免重复访问。但需要注意的是对于同一起点到同一终点有多条路径的时候,每次递归回溯时要重置visit[vi]的状态。并且可以使用vector来存储每次经过的节点。两个同类型的vector数组可以直接比较、直接赋值的,所以DFS也就可以简单的求出最佳路径。
DFS在递归过程中的还存在一个难点就是结束递归开始回溯的条件设置。这里往往在到达终点的基础还要加上题目所限定的条件。这有一个技巧就是先一个 if(begin == end && 题目限定的条件){到达终点后要处理的逻辑} if(begin == end){return;} 正所谓把逻辑处理和返回分离避免混乱(因为会存在有时需要执行逻辑有时不需执行逻辑的情况)。像PAT“周游世界”的题目中就存在这样的情况:第一次找到了能到达终点的路径此时还不需要去做任何比较就可以直接返回,但第二次、第三次、。。。都需要去执行逻辑比较判断每条路径经过的站数和换乘站次数。这里站数的统计很简单,每次递归执行就把站数加一。注意在dfs函数的参数中要想维护一个参数一定要加&(引用)。
接下来在说一个DFS中提升效率的方法:剪枝。以PAT“球队食物链”链为例,此题答案要求要满足排列{ a1 a2 ...aN }在字典序上小于排列{ b1 b2 ... bN },当且仅当存在整数K(1 <= K <= N),满足:aK < bK且对于任意小于K的正整数i,ai=bi。所以1号节点一定是答案集中的第一个元素,并且答案集的最后一个元素必须和第一个元素在邻接表所表示的图上是连通的。所以我们在每次递归前都检验一下接下来还没访问过点是否能到达1号节点,若不能的话就不进行之后的递归。
最后总结一下,dfs是图论最基本的一个遍历策略,适用于求路径数目,对于非层次遍历的题目都可考虑用次方法解决。但有时候会因时间复杂度的限制不得不放弃此方法。
简谈DFS的更多相关文章
- .NET简谈接口
自从面向对象开发方式的出现,抽象的概念就开始日新月异的发展,面向对象编程.面向接口编程.面向组件编程等等:这一系列的概念都是软件工程所追求的思想范畴,高类聚低耦合. 今天我要简谈的是面向对象里面非常重 ...
- .NET简谈构件系统开发模式
转自[王清培] http://www.cnblogs.com/wangiqngpei557/archive/2011/06/14/2080416.html 在本人的“.NET简谈插件系统开发模式”一文 ...
- .NET简谈——跨进高级编程门槛的必经之路
我们继续C#基础知识的学习,这篇文章对前面基础知识学习的朋友有着举足轻重的作用:为了延续基础知识学习的热情,我编写了这篇特殊的文章. 本篇文章的中心是想借“.NET简谈反射(动态调用)”一文继续发挥下 ...
- 浅谈DFS序
浅谈DFS序 本篇随笔简要讲解一下信息学奥林匹克竞赛中有关树的DFS序的相关内容. DFS序的概念 先来上张图: 树的DFS序,简单来讲就是对树从根开始进行深搜,按搜到的时间顺序把所有节点打上时间戳. ...
- 浅谈DFS,BFS,IDFS,A*等算法
搜索是编程的基础,是必须掌握的技能.--王主任 搜索分为盲目搜索和启发搜索 下面列举OI常用的盲目搜索: 1.dijkstra 2.SPFA 3.bfs 4.dfs 5.双向bfs 6.迭代加深搜索( ...
- 简谈Java语言的继承
Java语言的继承 这里简谈Java语言的三大特性之二——继承. Java语言的三大特性是循序渐进的.是有顺序性的,应该按照封装-->继承-->多态这样的顺序依次学习 继承的定义 百度百科 ...
- 简谈Java语言的封装
简谈Java语言的封装 封装的定义 封装将复杂模块或系统的逻辑实现细节隐藏,让使用者只需要关心这个模块或系统怎么使用,而不用关心这个模块或系统是怎么实现的. 在面向对象的的编程中,我们一般通过接口来描 ...
- MPI简谈
MPI简谈 MPI是分布式内存系统,区别于OpenMP和Pthreads的共享内存系统.MPI是一种基于消息传递的并行编程技术,是如今最为广泛的并行程序开发方法. MPI前世今生 MPI(Messag ...
- ASP.NET MVC 网站开发总结(六)——简谈Json的序列化与反序列化
首先,先简单的谈一下什么是序列化与反序列化,序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通 ...
随机推荐
- 分布式 ID 解决方案之美团 Leaf
分布式 ID 在庞大复杂的分布式系统中,通常需要对海量数据进行唯一标识,随着数据日渐增长,对数据分库分表以后需要有一个唯一 ID 来标识一条数据,而数据库的自增 ID 显然不能满足需求,此时就需要有一 ...
- java基础(六)--常用转义字符
1.换行:"\n"
- .Net Core in Docker极简入门(下篇)
Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 目录 前言 开始 Docker-Compose 代码修改 yml file up & down 镜像仓库 最后 前言 上一篇[. ...
- Python数据分析之股票数据
最近股市比较火,我7月初上车了,现在已经下了.中间虽然吃了点肉,但下车的时候都亏进去了,最后连点汤都没喝着. 这篇文章我们就用python对股票数据做个简单的分析.数据集是从1999年到2016年上海 ...
- Java开发环境配置之安装JDK
一:序言摘要 学习过Java的人都知道,如果想要开发一套java程序,首先需要做的准备工作就是配置JDK.JDK是 Java 语言的软件开发工具包,它主要用于移动设备.嵌入式设备上的java应用程序. ...
- scrapyd 部署
步骤 1 pip install scrapyd pip install scrapy-client 步骤 2 修改 scrapy.cfg [deploy:targetName]url = http: ...
- Django学习路20_流程复习
视频链接 https://www.bilibili.com/video/BV1rx411X717?p=21 千锋教育出品的 Django 课程 2020-05- ...
- 实现了__iter__和__next__的对象是迭代器
class MyList(object): """自定义的一个可迭代对象""" def __init__(self): self.items ...
- Python 字典(Dictionary) items()方法
描述 Python 字典(Dictionary) items() 函数以列表返回可遍历的(键, 值) 元组数组.高佣联盟 www.cgewang.com 语法 items()方法语法: dict.it ...
- PHP stat() 函数
定义和用法 stat() 函数返回关于文件的信息. 该函数将返回一个包含下列元素的数组: [0] 或 [dev] - 设备编号 [1] 或 [ino] - inode 编号 [2] 或 [mode] ...