目录
- 1.基本图算法
参见基本的图算法
参见深度优先搜索和广度优先搜索专题 - 2.最小生成树——无向图
参见最小生成树 - 3.单源最短路径
参见最短路径专题 - 4.所有结点对的最短路径问题
参见最短路径专题 - 5.最大流
参见最大流
1.基本图算法
- 图的表示包括邻接链表和邻接矩阵
- 广度优先搜索:算法需要在发现所有距离源节点s为k(k条边)的所有结点之后,才会发现距离源节点s为k+1的其他结点。
- 深度优先搜索:深度优先搜索总是对最近才发现的结点v的出发边进行搜索,直到该节点的所有出发边都被发现为止。一旦结点v的所有出发边都被发现,搜索则回溯到v的前驱结点,来搜索该前驱结点的其他出发边。
该过程一直持续到从源节点可以达到的所有结点都被发现为止。 - 拓扑排序(使用深度优先搜索):对于一个有向无环图G = (V, E)来说,其拓扑排序是G中所有结点的一种线性次序,该次序满足如下条件:
如果图G包含边(u ,v),则结点u在拓扑排序中出于结点v的前面(如果G含有回路,则不可能排出一个线性次序)。 - 强连通分量(使用深度优先搜索/拓扑排序):如果一个有向图中任意两个顶点互相可达,则该有向图是强连通的。有向图的强连通分量是“相互可达”关系下顶点的等价类。
有向图G = (V, E)的强连通分量是一个最大结点集合 C包含于V,对于该集合中的任一对结点u和v来说,路径 u ->...-> v和v ->...-> u同时存在,也就是u和v可以互相可达。
2. 最小生成树——无向图
- 使用贪心算法求解,关键在于对贪心选择性质和最优子结构的证明。
- Kruskal算法:集合A是一个森林,每次加入到集合A中的安全边永远是权重最小的连接两个不同分量的边。
- Prim算法(广度优先搜索):集合A是一棵树,每次加入到A中的安全边永远是连接A和A之外某个节点的边中权重最小的边。
3.单源最短路径
-
给定一个带权重的有向图G=(V, E)和权重函数w:E ->R,该权重函数将每条边映射到实数值的权重上。
图中一条路径p=<v0, v1, ..., vk>的权重w(p)是构成该路径的所有边的权重之和:
定义从结点u到结点v的最短路径权重δ(u, v)如下:
从结点u到结点v的最短路径则定义为任何一条权重为w(p) = δ(u, v)的从u到v的路径p。 最短路径问题
1)单源最短路径问题
给定一个图G=(V, E),希望找到从给定源节点s∈V到每个结点v∈V的最短路径。
2)单目的地最短路径问题
找到从每个结点v到给定目的地结点t的最短路径。如果将图的每条边的方向翻转过来,可以将该问题转换为单元最短路径问题
3)单节点对最短路径问题
找到从给定结点u到给定v的最短路径。如果解决了针对单个结点u的单源最短路径问题,那么也就解决了这个问题Bellman-Ford算法——O(VE)
对每条边调用|V| - 1次松弛操作。SPFA算法——对Bellman-Ford的一个改进(广度优先搜索)
建立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对u的所有邻接点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。有向无环图的按拓扑顺序进行松弛的算法——Θ(V + E)
非负权重有向无环图Dijkstra算法(贪心算法)(广度优先搜索)
算法维持集合S,从源节点s到该集合中每个结点之间的最短路径已经被找到。
算法重复从结点集V-S中选择最短路径估计最小的结点u,将u加入到集合S,然后对所有从u发出的边进行松弛。
二叉堆——O((V+E)lgV)
斐波那契堆——O(VlgV+E)差分约束系统——归约为单源最短路径问题(核心依据是三角不等式性质)
4.所有结点对的最短路径问题
所有结点对最短路径问题
对于每对结点u和v,找到从结点u到结点v的最短路径。基本方法和重复平方法——Θ(n4)和Θ(n3lgn)
1)动态规划
2)基本方法去掉一个不确定的边,需要遍历找到是哪个边
3)重复平方法与基本方法的区别在于:基本方法到最终解,每次增加一条边;重复平方法每次增加一倍。Floyd-Warshall——Θ(n3)
1)动态规划
2)Floyd-Warshall去掉中间一个确定的点,不用遍历求最小Johnson算法——O(V²lgV+VE)(稀疏图特别适合)
1)基于Bellman-Ford判断是否有负值环路
2)最大的特色是基于单源最短路径算法来进行,对每一点分别利用Dijkstra算法(时间效率最好的单源最短路径算法)
3)Dijkstra算法有限值,就利用“差分约束系统”里面的方法,利用三角不等式,将w'(u, v)变成非负的
5.最大流
5.1 最大流问题
(流网络)流网络G=(V, E)是一个有向图,图中每条边(u, v) ∈E有一个非负的容量值c(u, v) ≥ 0。
并且如果边集合E包含一条边(u, v),则图中不存在反方向的边(v, u)。
如果(u, v) ∉ E,定义c(u, v) = 0,且图中不允许自循环。
两个特殊结点:源结点s和汇点t。每个结点都在从源结点到汇点的某条路径上。即对于每个结点v∈V,流网络包含一条路径s -> v -> t。
因此,流网络是连通的,且由于源节点外每个结点都至少有一条进入的边,则|E| ≥ |V| -1。-
(流)设G=(V, E)是一个流网络,其容量函数为c。设s为网络的源结点,t为汇点。G中的流是一个实值函数f: V x V -> R,满足下面两条性质:
1)容量限制:对于所有的结点u, v ∈ V,要求 0 ≤ f(u, v) ≤ c(u, v)。
f(u, v)为从结点u到结点v的流。
2)流量守恒:对于所有的结点u ∈ V-{s, t},要求
当(u, v) ∉ E时,从结点u到结点v之间没有流,因此f(u, v) = 0. -
(流的值|f|)一个流f的值|f|定义如下:
流f的值是从源结点流程的总流量减去流入源结点的总流量。通常,一个流网络不会有任何进入源结点的边。也即后面的项为0. (最大流问题)在最大流问题中,给定一个流网络G、一个源结点s、一个汇点t,希望找到值最大的一个流。
5.2 四种解法(本质是两种解法:Ford-Fulkerson和推送—重贴标签算法)
-
Ford-Fulkerson方法——O(E|f*|)
Edmonds-Karp算法(Ford-Fulkerson方法的一种实现)——O(VE²)
这里主要是约定了查找增广路径的方法:寻找s到t的最短路径。
使用广度优先搜索来改善。
在残存网络中选择的增广路径是一条从源结点s到汇点t的最短路径,其中每条边的权重为单位距离。-
推送—重贴标签算法—— O(V²E)
-
前置重贴标签算法(推送—重贴标签算法的一种实现)—— O(V³)