单源点最短路径
---雨竹清风
单源最短路径:是从某一个源点s出发到图中的所有的顶点之间的最短路径。
1.单源点最短路径的变体:
1)单终点最短路径问题:找到从每一个顶点到终点的最短路径。可以将图中的边全部反向,然后求单源点最短路径即可。
2)单对顶点最短路径问题:对于图中的两个顶点u和v,找到从u到v的最短路径。
3)每对顶点间最短路径问题:找到图中的每对顶点之间的最短路径。
知识点:
①最短路径的子结构:
引理:最短路径的子路径是最短路径。
这是动态规划和贪心的算法。
②负权值边:
负权值是指边上的权值是负数,比如罚款。若图中存在负权回路,那么最短路径的定义就不对了,因为每次经过负权回路总是能够得到更小的权值。
③回路:
最短路径会包含回路吗?最短路径是不会包含回路的,不仅不能包含负权回路,而且是不能包含正权回路。因为若路径上存在一个环,我们将环移除之后便是一条更短的路径,所以说一条最短路径上不可能存在正权环。
④零权回路:
零权回路是指路径上存在一个环,环的权值是0,所以可以通过移除零权环路,便得到一条从源点s到v的一条无环回路。
2.最段路径的表示
最短路径上的顶点是源点可达的顶点的集合。最短路径树上的每一条路径便是从源点到某一个顶点的最短路径。[最短路径树:从源点到源点可达的顶点之间存在一条最短路径,这些最短路径便构成了最短路径树]在最短路径树上,源点到某一个顶点之间的唯一的简单路径便是从源点到该顶点的最短路径。
知识点:
松弛技术:
松弛表示紧缩上届的操作,即对于从源点到该结点的最短路径的修改。若用d.u,d.v表示从源点到u,v的最短路径 ,那么d.v ≤d.u+w(u,v)这个不等式必须满足,这个不等式的约束是比较松弛的,所以称为松弛技术。若在松弛之前d.v >d.u+w(u,v),那么经过松弛之后,即条件满足修改d.v的值,令d.v = d.u+w(u,v),因此d.v的值会减少。若在松弛之前d.v ≤d.u+w(u,v),那么d.v不会修改。
3.Bellman-Ford算法
解决的问题:Bellman-Ford算法能够在一般的情况(存在负权环路)下,解决单源点最短路径问题。
Bellman-Ford算法将对每一条边进行松弛操作,共进行|v|-1次;本算法将会返回一个布尔值,布尔值的作用是判断该图中是否存在负权回路,若该布尔值为false则存在负权回路,那么问题无解,否则问题有解。
伪代码如下:
为什么循环n-1次即可?
因为最短路径肯定是个简单路径,不可能包含回路的,如果包含回路,且回路的权值和为正的,那么去掉这个回路,可以得到更短的路径。如果回路的权值是负的,那么肯定没有解了,图有n个点,又不能有回路,所以最短路径最多n-1边。又因为每次循环,至少relax一边,所以最多n-1次就行了。
为什么还需要进行检测是否存在负权环?
因为对于图中的n-1次松弛操作并没有保证一定没有负权环,若有负权环,那么对于图中进行n-1次松弛操作结论依然成立。所以一定要检测是否存在负权环。
检测负权环的思想:将图中所有的边进行一次检测,检查是否存在(u,v,w)这么一条边,使得v.d > u.d + w,若存在则说明会有负权环的存在,所以问题无解。若不存在,那么有解。
图解bellman-ford算法:
给定一个松弛边的顺序:
(t,x) (t,y) (t,z) (x,t) (y,x) (y,z) (z,x) (z,s) (z,t)
原图:
顶点上的值代表从源结点s到v的最短路径上权值的上界,初始化为无穷。