在下最近刷了几道DAG图上dp的题目。
要提到的第一道是NOIP原题《最优贸易》。这是一个缩点后带点权的DAG上dp,它同时规定了起点和终点
第二道是洛谷上的NOI导刊题目《最长路》,一个裸的DAG上dp,也同时规定了起点和终点
对于这两道题目,我分别用了两种不同的方法来写。
第一道题目,我建立了一个反向图,从起点和终点分别用两张图来进行Floodfill,若某个点不能被两遍Floodfill遍历到,则这个点是无用点,应当剔除。这样是为了方便后面作DAG上dp时,使用拓扑序来进行过程。
第二道题目,我直接用了spfa,把松弛的条件的小于号改成大于号。
而后我才发现,第一题也可以用spfa写。

这是为什么?

我想了一下。首先spfa跑最长路,它得保证是一张DAG。否则你可以在一个正权环上无限的松弛下去。
其次考虑一下最长路的DAG拓扑序dp做法。
是不是一个点,能够更新它的状态的点的状态全部被确定了,它的状态才能够被确定?
然而SPFA并不是这么做的。因为类似BFS过程的缘故,可能一条路径已经早就更新了这个点的状态,而另一条能松弛它的路径还没能更新它的点状态。
这样子得到的结果会是错误的吗?并不会。 SPFA有效的避免了错解情况的发生。

讨论以下情况:
a->b 路径A:中间有几个点 路径B:中间有十几个点。
b->c 只有一条路径。
a的入度为0。

DAG-dp情况:
首先从a开始拓扑序dp。显然a->b 路径上的所有点的状态确定下来后,b的状态被确定,随后b->c的状态一个个地被确定。

SPFA情况:
由于BFS缘故,路径A上的点首先被确定状态。随后b->c依次被更新状态,但是路径B能得到更优的答案。
随后,路径B跟上来了。它更新了b的状态,b随后再次被放入处理队列中,依次而来的,b->c上面的点一个个地再次重新入队,再次被更新状态。

因此,使用SPFA进行类似最长路的DAG上dp时,每个点的最终状态跟拓扑序dp一样,会是最优的。这就是为什么SPFA能跑DAGdp的原因。
什么时候使用SPFA跑DAG会更好呢?确定了起点和终点的状况下。 如我原先所用的方法,我做了两遍FloodFill,又删了一遍点,还要作各种判断,才能避免其它点对拓扑序dp的干扰。但是使用SPFA,从起点开始松弛,直接松弛到终点的最优状态,它有效的兼顾了DAGdp所应该得到的最优状态,而又避免了拓扑序更新状态的条件之一——入度必须为0.因为这么做,显然会受到其它多余点(起点不能到的点/不能到终点的点)的干扰。
两者的复杂度如何呢?如果不考虑起点和终点的条件,拓扑序肯定更优。但如果考虑起点和终点的条件,综合考虑代码复杂度和时间复杂度,我觉得我应该会写SPFA。

感觉值得做个记录....qwq

UPD

有时候是可以不用排除多余点的。
也就是说,只用给起点设置初始状态,其它的状态全部不设
那么作拓扑排序得到的结果也应该与排除多余点等价
大部分题目应该都是如此。

[正经分析] DAG上dp两种做法的区别——拓扑序与SPFA的更多相关文章

  1. DAG上dp思想

    DAG上DP的思想 在下最近刷了几道DAG图上dp的题目.要提到的第一道是NOIP原题<最优贸易>.这是一个缩点后带点权的DAG上dp,它同时规定了起点和终点.第二道是洛谷上的NOI导刊题 ...

  2. jqGrid中实现radiobutton的两种做法

    http://blog.sina.com.cn/s/blog_4f925fc30102e27j.html   jqGrid中实现radiobutton的两种做法 ------------------- ...

  3. SqlServer保留几位小数的两种做法

    SqlServer保留几位小数的两种做法   数据库里的 float momey 类型,都会精确到多位小数.但有时候 我们不需要那么精确,例如,只精确到两位有效数字. 解决: 1. 使用 Round( ...

  4. 软件公司的两种管理方式 总体来说,这个世界上存在两种不同的软件公司的组织结构。我把他们叫做 Widget Factory(小商品工厂) 和 Film Crews(电影工作组

    软件公司的两种管理方式 一个简单的回答应该是——“因为在我们的社会里,我们总是会认为薪水和会和职位的层次绑在一起”.但是,这个答案同时也折射出一个事实——我们的薪资是基于我们的所理解的价值,但这并没有 ...

  5. bzoj1093: [ZJOI2007]最大半连通子图 scc缩点+dag上dp

    一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G'=(V ...

  6. ACE_linux:Reactor与Proactor两种模式的区别

    一.概念: Reactor与Proactor两种模式的区别.这里我们只关注read操作,因为write操作也是差不多的.下面是Reactor的做法: 某个事件处理器宣称它对某个socket上的读事件很 ...

  7. jsp中两种include的区别【转】

    引用文章:http://www.ibm.com/developerworks/cn/java/j-jsp04293/ http://www.cnblogs.com/lazycoding/archive ...

  8. 什么是CS和BS结构,两种结构的区别

    什么是CS和BS结构,两种结构的区别 什么是C/S和B/S结构?         C/S又称Client/Server或客户/服务器模式.服务器通常采用高性能的PC.工作站或小型机,并采用大型数据库系 ...

  9. Ajax的get和post两种请求方式区别

    Ajax的get和post两种请求方式区别 (摘录):http://ip-10000.blog.sohu.com/114437748.html 解get和post的区别. 1. get是把参数数据队列 ...

随机推荐

  1. Spring boot错误处理以及定制错误页面

    如果是浏览器访问,返回错误页面 注意浏览器发送请求的请求头:  注意区别其他客户端哦比如 postman 如果是其他客户端,返回一个Json数据 原理可以参照ErrorMvcAutoConfigura ...

  2. cocos2d-js入门二 环境搭建二

    电脑升级到WIN10后,cocos  code IDE安装不成功. 于是搭建新的环境JetBrainsWebStorm+chrome+JetBrains IDE Support,其中JetBrains ...

  3. vue中watch的用法

    一.首先确认watch是一个对象,一定要当做对象来用 watch:{ } 对象:有键,有值. 1.键:就是你要监控的那个家伙,比如说$route,这个就是要监控路由的变化.或者是data中的某个变量. ...

  4. 远程使用tomcat8的首页的管理工具

    1.在%Tomcat_Home%/conf/Catalina/localhost中新建manager.xml,内容如下 <Context privileged="true" ...

  5. bzoj2049: [Sdoi2008]Cave 洞穴勘测 lct裸题

    题意:三种操作一种摧毁一条边,一种链接一条边,一种查询两个点是否联通 题解:lct的link和cut即可 /********************************************** ...

  6. HDU 4122 单调队列

    转载自:http://blog.csdn.net/lvshubao1314/article/details/46910271 DES :给出n个订单和m是商店的开放时间.然后n行给出n个订单的信息.然 ...

  7. MVC Ajax Helpers

    在MVC中要实现Ajax有很多的方式,有微软自己的MicrosoftAjax,也可以用JQuery的AJax来实现,如果对其他的JavaScript框架熟悉,还可以采用其他的实现方案,比如说Proto ...

  8. C++设计模式之备忘录模式

    备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态[DP].举个简单的例子,我们玩游戏时都会保存进度,所保存的进度以文件的 ...

  9. 【LeetCode 225_数据结构_栈_实现】Implement Stack using Queues

    class Stack { public: // Push element x onto stack. void push(int x) { int len = nums.size(); nums.p ...

  10. L204

    Riding a bike is good exercise and great fun. But what do you do with a bike after you outgrow it? N ...