在下最近刷了几道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. 解决margin重叠的问题

    margin重叠有两种情况: 1.兄弟级的垂直块之间,margin这个属性上下边距,会发生重叠的情况 解决办法:float浮动或display:inline-block 2 .父子级的块之间,子级的上 ...

  2. curl使用介绍

    linux curl是通过url语法在命令行下上传或下载文件的工具软件,它支持http,https,ftp,ftps,telnet等多种协议,常被用来抓取网页和监控Web服务器状态. 一.Linux ...

  3. C# .NET 开发心得

    1. 工作路径问题 1. 多项目构成的解决方案,Web APP作为启动项目时的工作路径 //当前执行的exe文件名 //C:\\Program Files\\IIS Express\\iisexpre ...

  4. Codeforces Round #394 (Div. 2) C.Dasha and Password(暴力)

    http://codeforces.com/contest/761/problem/C 题意:给出n个串,每个串的初始光标都位于0(列)处,怎样移动光标能够在凑出密码(每个串的光标位置表示一个密码的字 ...

  5. LA 4253 箭术(二分枚举)

    https://vjudge.net/problem/UVALive-4253 题意: 有n个平行于x轴的线段,每条线段代表一个靶子.判断是否可以站在x轴上[0,W]区间内的某个位置射箭. 思路:二分 ...

  6. linux find/grep 与cat联合使用

    find ./ -name  file_name.txt   | xargs cat >> file_name.txt

  7. nodejs项目的model操作mongo

    想想以前学习hibernate的时候,学习各种表和表之间的映射关系等一对多,多对一,多对多,后来到了工作中,勇哥告诉我, 那时在学习的时候,公司中都直接用外键关联. 这里我们学习下,如何在Nodejs ...

  8. UVA-10410 Tree Reconstruction (树重建)

    题目大意:给出对一棵树的BFS遍历序列和DFS遍历序列,求出每一个节点的子节点. 题目分析:在BFS的序列中,子节点的下标一定比父节点的下标至少大1(根节点与第一个子节点除外),即pos[fa]+1& ...

  9. LTE空口协议——是空口3GPP协议 不是网络IP协议

    [LTE基础知识]LTE空口协议分析 from:https://www.mscbsc.com/viewnews-102038.html控制面协议 控制面协议结构如下图所示. PDCP在网络侧终止于eN ...

  10. FireFox和IE下使用Date来构造新Date对象的BUG

    正常方式 我们都知道可以使用new Date()来创建一个Date对象. new Date();//Date {Mon Jun 15 2015 15:53:16 GMT+0800} 也可以用new D ...