基于深度优先的回溯算法框架

很多复杂点儿的问题都要用树或图来建模,树和图最基础的操作是遍历,但是有时候我们并不需要访 问每个结点。比如问你,中国地图上有镇江这个城市吗?那你肯定是找到就立马告诉我,而不会傻拉吧唧 地把每个城市都看一遍,即使找到了镇江也闷头向前。在这里我想为这一类问题提供一个算法的框架,降 低思维复杂度。

当然图的深度优先是基础,我在这里大概讲一下,读者有兴趣可以去看《算法导论》。图是由结点和 边组成的,深度优先的思想就是如果通过当前访问的结点还能跟踪到未访问的结点,那么就继续访问,这 也是“深度优先”这个名字的由来。按照这个描述,我们肯定要用变量来标识结点是否已经被访问,《算 法导论》用三种颜色 ——

白色: 还没被访问;

灰色: 即将被访问;

黑色: 已经访问过了,并且由此结点所跟踪到的结点也全都被访问过了。

我们每次访问一个结点时都问自己,现在是个什么状况?通常有以下三种 ——

好的,我已经能解决这个问题了: OK,直接返回就可以了,因为已经找到答案了;

还不能作出任何判断: 这样的话我们只能继续遍历咯;

虽然还不能对结果作出明确的判断,但是我们能确定后面结点无需再访问:回溯,然后返回。

于是深度优先的框架就出来了:

#define WHITE 0
     #define GRAY 1
     #define BLACK 2
     #define KNOWN 1       /* 已经能确定答案 */
     #define UNKOWN 2      /* 一无所知 */
     #define CUT 3         /* 能确定可以剪枝 */
     void DFS(void) {
         /* 最开始每个结点都没被访问 */
         for every node i in graph {
             color[i] = WHITE;
         }
         /*
          *要对每个结点都调用DFS_visit,
          *这是为了处理非连通图。
          *如果你已经能确定图是连通的,
          *那么只要对一个结点调用DFS_visit就可以了
          */
         for every white node v in graph {
             if (color[v]==WHITE)    DFS_visit(v);
         }
     }
     void DFS_visit(v) {
         color[v] = GRAY;
         state = test(v); //评估当前的状况
         if (state==KNOWN) {
             //do something
             return ;
         } else if (state==CUT) {
             color[v] = BLACK;
             // trace back
             return;
         }
         for every node u adjacent to v {
             if (color[u]==WHITE)    DFS_visit(v);
         }
         color[v] = BLACK;
         // trace back 
     }

你可以用这个框架去试着解决 POJ3740,或者自己去找些问题。如果发现此文错误请在此博客留言或 通过邮箱联系我。

出处:http://www.cnblogs.com/john-d/archive/2010/01/03/1638258.html

时间: 2024-09-14 18:30:21

基于深度优先的回溯算法框架的相关文章

DockOne微信分享(一三一):Juice——一种基于MesosFramework的任务云框架

本文讲的是DockOne微信分享(一三一):Juice--一种基于MesosFramework的任务云框架[编者的话]近年来,随着Mesos在生产环境中的普及,使大规模的集群管理变得简单,而基于MesosFramework开发的Juice框架,能够完成分布式任务的分发,处理,对于资源利用率的提高有很大的帮助,今天就为大家介绍一下这套框架. [3 天烧脑式容器存储网络训练营 | 深圳站]本次培训以容器存储和网络为主题,包括:Docker Plugin.Docker storage driver.D

基于.NET平台常用的框架整理

原文:基于.NET平台常用的框架整理 转:http://www.cnblogs.com/hgmyz/p/5313983.html 自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累了一些开源的组件,就目前想到的先整理于此,如果再想到,就继续补充这篇日志,日积月累,就能形成一个自己的组件经验库. 分布式缓存框架: Microsoft Velocity:微软自家分布式缓存服务框架. Memcahed:一套分

联想企业网盘基于Docker构建分布式部署框架实践

本文讲的是联想企业网盘基于Docker构建分布式部署框架实践[编者的话]本文首先介绍了企业级分布式系统部署所面临的挑战,并且结合联想云存储自有框架研发经验分享了一些解决问题的思想和具体做法.最后还与Kubernetes项目进行了简单对比. 众所周知,企业网盘在这两年呈现爆发式增长,越来越多的企业选择企业网盘,来解决企业在业务过程中面临的数据集中存储.共享.分发.协同办公以及移动化等痛点需求.同时将企业网盘整合到各个业务系统中,大幅提高企业的数据流转效率和安全! 而联想企业网盘增长尤为迅速,仅联想

基于.NET平台常用的框架和开源程序整理_自学过程

自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累了一些开源的组件,就目前想到的先整理于此,如果再想到,就继续补充这篇日志,日积月累,就能形成一个自己的组件经验库. 分布式缓存框架: Microsoft Velocity:微软自家分布式缓存服务框架. Memcahed:一套分布式的高速缓存系统,目前被许多网站使用以提升网站的访问速度. Redis:是一个高性能的KV数据库. 它的出现很大程度补偿了Mem

基于MVC模式的Struts框架研究与应用

摘要: Struts框架具有组件的模块化,灵活性和重用性的优点,同时简化了基于MVC的web应用程序的开发.本文讨论了Struts框架实现MVC模式的原理与方法,给出了一个具体的应用实例. 分布式企业应用软件结构复杂.涉及多种技术,对设计开发人员提出了很高的要求.在此情况下,运用设计模式――可复用的设计方案进行软件的设计开发十分必要.MVC模式已被证明是一种成功的软件设计模式,本文主要讨论了一种实现MVC模式的应用框架――Struts,并通过一个实例展示了Struts框架实现MVC模式的方法.

基于JavaScript的REST客户端框架

现在REST是一个比较热门的概念,REST已经成为一个在Web上越来越常用的应用,基于REST的Web服务越来越多,包括Twitter在内的微博客都是用REST做为对外的API,先前我曾经介绍过"基于REST架构的Web Service设计",并给出了一些服务器端和客户端代码,随着JavaScript的广泛应用,我这里就给出一个轻量级的基于JavaScript的REST客户端框架. 这个JavaScript客户端主要使用了XMLHttpRequest对象来实现通过HTTP对服务器操作G

基于Spring-DM实现分布式服务框架(DSF)(一)

经过上篇分析分布式服务框架的blog后,正式对之前的基于OSGi实现分布式服务框架的系列改名(顺便把分布式服务框架改为使用DSF缩写),因为已经决定基于Spring-DM来实现,为什么呢,而且为什么一定要是Spring-DM,而不直接说Spring呢? 今天是Spring-DM 1.0 release的大好日子,,不容易呀,做了这么久,具体怎么样还没来得及细看,不过之前有用过1.0 m2,已经觉得很不错了,相信1.0 release更不会失望. 在我眼里看来,Spring是个很大的东西,其实DS

基于OSGi实现分布式服务框架历程(二)

在这篇历程中来完成对于JINI的Spike,目标仍然是判断基于JINI实现服务的路由.查找需求的满足度. JINI是由Sun研究院制定的,其目标就是为了实现分布式的服务,所以在很多地方可以看到它和分布式服务框架是有不少重叠之处的,来先看看它对于需求的满足度,最后再来分析做个总结. 1.怎么实现远程的将服务注册到服务中心? 在jini中暂时没有找到远程注册服务到服务中心的方法. jini的服务需要和服务中心部署在同一台机器上,这个倒是可以通过服务管理中心直接将sar格式的服务部署上去,支持服务的动

基于OSGi实现分布式服务框架历程(一)

写完之前的那篇基于OSGi实现服务框架的分析后,决定动手来实现一个基于OSGi的分布式服务框架,而其feature呢,就会遵照之前写的服务框架的要素来实现,根据之前的分析,将这个实现过程分为了三个大的步骤来完成:Spike阶段.实现阶段和测试阶段,Spike阶段用于完成几个关键问题的技术的研究和选型:实现阶段用于完成基于OSGi的分布式服务框架:测试阶段用于判断实现的分布式框架对于应用场景的符合程度.性能的情况. 首先进入Spike阶段,在Spike阶段需要完成服务注册.创建以及服务的proxy