所谓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的更多相关文章

  1. .NET简谈接口

    自从面向对象开发方式的出现,抽象的概念就开始日新月异的发展,面向对象编程.面向接口编程.面向组件编程等等:这一系列的概念都是软件工程所追求的思想范畴,高类聚低耦合. 今天我要简谈的是面向对象里面非常重 ...

  2. .NET简谈构件系统开发模式

    转自[王清培] http://www.cnblogs.com/wangiqngpei557/archive/2011/06/14/2080416.html 在本人的“.NET简谈插件系统开发模式”一文 ...

  3. .NET简谈——跨进高级编程门槛的必经之路

    我们继续C#基础知识的学习,这篇文章对前面基础知识学习的朋友有着举足轻重的作用:为了延续基础知识学习的热情,我编写了这篇特殊的文章. 本篇文章的中心是想借“.NET简谈反射(动态调用)”一文继续发挥下 ...

  4. 浅谈DFS序

    浅谈DFS序 本篇随笔简要讲解一下信息学奥林匹克竞赛中有关树的DFS序的相关内容. DFS序的概念 先来上张图: 树的DFS序,简单来讲就是对树从根开始进行深搜,按搜到的时间顺序把所有节点打上时间戳. ...

  5. 浅谈DFS,BFS,IDFS,A*等算法

    搜索是编程的基础,是必须掌握的技能.--王主任 搜索分为盲目搜索和启发搜索 下面列举OI常用的盲目搜索: 1.dijkstra 2.SPFA 3.bfs 4.dfs 5.双向bfs 6.迭代加深搜索( ...

  6. 简谈Java语言的继承

    Java语言的继承 这里简谈Java语言的三大特性之二——继承. Java语言的三大特性是循序渐进的.是有顺序性的,应该按照封装-->继承-->多态这样的顺序依次学习 继承的定义 百度百科 ...

  7. 简谈Java语言的封装

    简谈Java语言的封装 封装的定义 封装将复杂模块或系统的逻辑实现细节隐藏,让使用者只需要关心这个模块或系统怎么使用,而不用关心这个模块或系统是怎么实现的. 在面向对象的的编程中,我们一般通过接口来描 ...

  8. MPI简谈

    MPI简谈 MPI是分布式内存系统,区别于OpenMP和Pthreads的共享内存系统.MPI是一种基于消息传递的并行编程技术,是如今最为广泛的并行程序开发方法. MPI前世今生 MPI(Messag ...

  9. ASP.NET MVC 网站开发总结(六)——简谈Json的序列化与反序列化

    首先,先简单的谈一下什么是序列化与反序列化,序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通 ...

随机推荐

  1. 使用recv函数和send函数的技巧

    一些述说 recv函数用于socket通信中接收消息,接口定义如下: int recv(SOCKET s, char *buf, int len, int flags) 参数一:指定接收端套接字描述符 ...

  2. Spring中异步注解@Async的使用、原理及使用时可能导致的问题

    前言 其实最近都在研究事务相关的内容,之所以写这么一篇文章是因为前面写了一篇关于循环依赖的文章: <面试必杀技,讲一讲Spring中的循环依赖> 然后,很多同学碰到了下面这个问题,添加了S ...

  3. SW算法求全局最小割(Stoer-Wagner算法)

    我找到的唯一能看懂的题解:[ZZ]最小割集Stoer-Wagner算法 似乎是一个冷门算法,连oi-wiki上都没有,不过洛谷上竟然有它的模板题,并且2017百度之星的资格赛还考到了.于是来学习一下. ...

  4. java8之Stream流处理

    简介 Stream 流处理,首先要澄清的是 java8 中的 Stream 与 I/O 流 InputStream 和 OutputStream 是完全不同的概念. Stream 机制是针对集合迭代器 ...

  5. .Net Core 项目开发中的Errors,Exceptions

    这个错误是在连接数据库的时候,没有找到对应的表, namespace TodoApi.Models { public class TodoContext : DbContext { public To ...

  6. 图书馆管理系统程序+全套开发文档(系统计划书,系统使用说明,测试报告,UML分析与设计,工作记录)

    图书馆管理系统程序+全套开发文档(系统计划书,系统使用说明,测试报告,UML分析与设计,工作记录): https://download.csdn.net/download/qq_39932172/11 ...

  7. phpcms根据二级栏目列表写的三级栏目列表

    <div class="container"> <!--左边树状导航--> <div class="CNLTreeMenu" id ...

  8. Linux图形界面与命令行界面以及用户之间的转换

    刚刚不小心进入了命令行界面,,,,,, ALT SHIFE F5 咋回去的呢 sudo startx 但是回去以后默认是root ,,,,,, 所以切换用户 su username//用户名 就可以切 ...

  9. Python字符串更新

    Python字符串更新:截取字符串的某一部分 和 其他字符串进行拼接. 注:可以修改字符串的值,但修改的不是内存中的值,而是创建新的字符串. 1.使用字符串常量进行更新: # 使用字符串常量 strs ...

  10. Python unichr() 函数

    描述 unichr() 函数 和 chr() 函数功能基本一样, 只不过是返回 unicode 的字符.高佣联盟 www.cgewang.com 注意: Python3 不支持 unichr(),改用 ...