level 13
表示看了半天没看懂
不都是if(dist[j]+edge[j][u]<dist[u])么,为啥dij在有负边时就会有错呢,两个有啥区别呢。。。
2012年10月21日 13点10分
1
level 6
edge[s][j]+edge[j][u]>=shortest_dist[u]
这是著名的三角不等式
dist[j]+edge[j][u]<dist[u]
这里是 松弛(relax) 操作的判断句,松弛 是Bellman-Ford,Dijkstra,SPFA等算法的核心
2012年10月21日 14点10分
4
那有什么区别呢
2012年10月21日 14点10分
回复 轩轩醉了 :bellman-ford就是让你理解松弛是个什么玩意,实际中几乎不会用到,去看一下简单好用的SPFA你就能把它连带Dijkstra都甩了
2012年10月21日 14点10分
回复 奇特空 :spfa把dijkstra甩掉了? 笑尿了.
2012年10月21日 15点10分
回复 wyl8899 :写起来比spfa麻烦,还只在无负权边的稠密图采用,对于想拿1=的完全可以甩(至少我这里是的)
2012年10月21日 15点10分
level 12
区别大了……
Dijkstra是单源最短路径(一个点到其他点的最短路),基于贪心,朴素是O(V^2+E),用堆写可以到O((V+E) lg V)
Floyd是多源(所有点两两之间的最短路径),基于著名的松弛原理,O(V^3)
2012年10月21日 15点10分
6
Dijkstra也有用到松弛
2012年10月21日 15点10分
Dij的前提就是假定边权为正,负边用SPFA吧
2012年10月21日 15点10分
额,ford啊,看错了……
2012年10月21日 15点10分
level 8
要理解算法是什么原理啦。。
dij是贪心,每次只选择未确定下来答案的、距离原点最近的点往外扩展更新,也就是每次都能确定一个点到原点的最终答案,并且这个值确定下来之后不会改变。在边权非负的情况下,每次确定的答案一定是递增的。所以对于某个点来说,它的dist一定是周围已经确定了dist的那些点更新的,而未确定dist的点无权更新它(而且因为它先被确定而周围的点在其后,所以它们的dist也一定比它的dist要大)。但是有负边权之后构造一个反例非常容易。
ford(应该叫floyd)是动态规划,我们看见的f[i,j]=min(f[i,j],f[i,k]+f[k,j])只是其简化版本,原版的floyd是三维的。f[i,j][k]表示:从i走到j只经过【前k个点】中的某些点,得出的最短路。每次k+1之后执行那个式子,相当于用点k来松弛i~j这条路径(类似于f[k]=opt{f[k-1]}——这里f的每个元素是一个矩阵——这就是为什么一定要先循环k),所以最终i~j这条路径被所有点松弛了一遍,也就是“从i~j经过任意某些点的最短路”,也就是最终i~j的最短路了。人们发现,在k的每遍循环中,f[i,j]仅被更新了一次,换句话说f[i,j][k]仅与f[i,j][k-1]有关。所以k那一维空间可以节约掉,就变成现在这样了。
2012年10月21日 15点10分
7
他说"都是if(dist[j]+edge[j][u]<dist[u])么",目测ford是指bellman-ford而不是floyd
2012年10月21日 15点10分
回复 奇特空 :好吧,bellman-ford我们都没学,直接被某学长带着学SPFA。。目测ford和floyd原理类似,也是某条路径被所有点松弛了一遍。。
2012年10月21日 15点10分
回复 RexSkz :ford和flyod差多了吧......ford就是对每条边不停地松弛,当你觉得松弛得不能再松弛的时候就可以收手了......效率低得无法直视,你们学长的做法是正确的
2012年10月21日 15点10分
回复 奇特空 :好吧没学就是不行>_<。。个人觉得SPFA当做一个全新的算法学也没什么问题。。
2012年10月21日 15点10分