所谓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. Spring IoC深入理解

    本文相关代码(来自官方源码spring-test模块)请参见spring-demysify org.springframework.mylearntest包下. 三种注入方式 1.构造方法注入 pub ...

  2. JavaScript以万或亿为单位显示,并保留两位小数或取整

    //单位:万 n = 814308678.00; n = Math.floor((n /10000) * 100) / 100; //保留小数点两位 //n = parseInt((n /10000) ...

  3. 搭建kubernetes集群

    什么是Kubernetes? Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展.如果你曾经用过Docker容器技术部署容器,那么可以将Docker看成K ...

  4. Java基础之函数

    函数(方法)的定义: 函数就是定义在类中的具有特定功能的一段独立的小程序. 为什么有函数:为了提高代码的复用性,对独立代码进行抽取,把抽取部分代码部分,定义成一个独立的功能,方便日后使用.Java中对 ...

  5. linux cp 拷贝不覆盖源文件

    cp 参数 CP() User Commands CP() NAME cp - copy files and directories SYNOPSIS cp [OPTION]... [-T] SOUR ...

  6. JavaScript高级程序设计(第三版) 7/25

    第七章 函数表达式 1.定义函数的方式有两种,一种是函数声明,一种是函数表达式. //函数声明 function fuc (a){ } //函数表达式 var fuc = function(a){ } ...

  7. PHP uasort() 函数

    ------------恢复内容开始------------ 实例 使用用户自定义的比较函数对数组 $arr 中的元素按键值进行排序: <?phpfunction my_sort($a,$b){ ...

  8. PHP abs() 函数

    实例 返回不同数的绝对值: <?phpecho(abs(6.7) . "<br>");echo(abs(-6.7) . "<br>" ...

  9. PHP xml_parser_set_option() 函数

    定义和用法 xml_parser_set_option() 函数为 XML 解析设置选项.高佣联盟 www.cgewang.com 如果成功,该函数则返回 TRUE.如果失败,则返回 FALSE. 语 ...

  10. PHP bin2hex() 函数

    实例 把 "Hello World!" 转换为十六进制值: <?php 高佣联盟 www.cgewang.com$str = bin2hex("Hello Worl ...