gitbook-way-to-algorithm
  • Introduction
  • Preface 前言
  • Content 目录
  • MathSymbolTable 数学符号表
  • Chapter-1 BasicKnowledge 第1章 基础知识
    • TimeComplexity 时间复杂度
    • Recursion 递归式
  • Chapter-2 Sort 第2章 排序
    • InsertSort 插入排序
    • BubbleSort 冒泡排序
    • QuickSort 快速排序
    • MergeSort 归并排序
  • Chapter-3 Search 第3章 搜索
    • BinarySearch 二分查找法(折半查找法)
    • AdditionMultiplicationPrinciple 加法乘法原理
    • BruteForce 暴力枚举
    • Recursion 递归
    • BreadthFirstSearch 广度优先搜索
    • BidirectionalBreadthSearch 双向广度搜索
    • AStarSearch A*搜索
    • DancingLink 舞蹈链
  • Chapter-4 DataStructure 第4章 数据结构
    • DisjointSet 并查集
    • PrefixTree(TrieTree) 前缀树
    • LeftistTree(LeftistHeap) 左偏树(左偏堆)
    • SegmentTree 线段树
    • FenwickTree(BinaryIndexedTree) 树状数组
    • BinarySearchTree 二叉查找树
    • AVLTree AVL平衡树
    • RedBlackTree 红黑树
    • SkipList 跳跃表
    • BPlusTree B+树
    • BMinusTree B-树
  • Chapter-5 DynamicProgramming 第5章 动态规划
    • Section-1 LinearDP 第1节 线性动规
      • LongestCommonSubsequence 最长公共子序列
      • LongestIncreasingSubsequence 最长递增子序列
      • BidirectionalSubsequence 双向子序列
      • MaximumContinuousSubsequenceSum 最大连续子序列和
      • LongestPalindromicSubsequence 最长回文子序列
    • Section-2 BagDP 第2节 背包问题
      • 01-Bag 01背包
      • CompleteBag 完全背包
      • TwoDimensionBag 二维背包
    • Section-3 RegionalDP 第3节 区域动规
      • MinimumMergeCost - 最小合并代价
      • UniquePath 唯一路径
      • TrianglePath 三角形路径
    • Section-4 TreeDP 第4节 树形动规
      • MaximumBinaryTree 最大二叉树
      • MaxMultipleTree 最大多叉树
      • MaximumBinaryTreeRadiusSum 最大二叉树和
  • Chapter-6 GraphTheory 第6章 图论
    • Section-1 Traverse 第1节 遍历
      • DepthFirstSearch 深度优先搜索
      • BreadthFirstSearch 广度优先搜索
      • TopologicalSort 拓扑排序
      • EulerCycle 欧拉回路
    • Section-2 MinSpanningTree 第2节 最小生成树
      • Kruskal Kruskal算法
      • Prim Prim算法
    • Section-3 ShortestPath 第3节 最短路径
      • BellmanFord BellmanFord算法
      • Dijkstra Dijkstra算法
      • FloydWarshall FloydWarshall算法
      • DifferentConstraints 差分约束
    • Section-4 StronglyConnectedComponents 第4节 强连通分支
      • Kosaraju Kosaraju算法
      • Tarjan Tarjan算法
      • 2-SAT 2-SAT问题
    • Section-5 NetworkFlow 第5节 网络流
      • EdmondsKarp EdmondsKarp算法(最短路径增广算法)
      • PushRelabel 压入与重标记算法
      • Dinic - Dinic算法
      • MinimumCostFlow - 最小费用流
      • MultipleSourceMultipleSinkMaxflow - 多源点多汇点最大流
    • Section-6 BinaryMatch 第6节 二分匹配
      • Hungarian 匈牙利算法
      • HopcroftKarp Hopcroft-Karp算法
      • MatchToMaxflow 二分匹配转化为最大流
      • KuhnMunkres Kuhn-Munkres算法
      • Introduction-Domination,Independent,Covering,Clique 介绍支配集、独立集、覆盖集和团
      • WeightedCoveringAndIndependentSet 最小点权覆盖和最大点权独立集
      • MinimumDisjointPathCovering 最小不相交路径覆盖
      • MinimumJointPathCovering 最小可相交路径覆盖
      • Coloring 染色问题
  • Chapter-7 CombinatorialMathematics 第7章 组合数学
    • FullPermutation 全排列
    • Combination 组合
    • Permutation 排列
    • PermutationGroup 置换群
  • Chapter-8 NumberTheory 第8章 数论
    • PrimeSieve 素数筛法
    • GreatestCommonDivisor 最大公约数
    • Euclid 欧几里得算法
    • ExtendedEuclid 扩展欧几里得算法
    • ChineseRemainerTheorem 中国剩余定理
    • ModularExponentiation 模幂运算
  • Chapter-9 LinearAlgebra 第9章 线性代数
    • Section-1 Matrix 第1节 矩阵
      • Strassen Strassen算法
      • GaussElimination 高斯消元法
      • LUP LUP分解
      • InverseMatrix 矩阵求逆
    • Section-2 LinearProgramming 第2节 线性规划
      • Simplex 单纯形算法
      • Dinkelback Dinkelback算法
  • Chapter-10 AnalyticGeometry 第10章 解析几何
    • Section-1 Polygon 第1节 多边形
      • Cross 向量叉积
      • SegmentIntersection 线段相交
      • Sweeping 扫除算法
      • ConvexPolygonArea 凸多边形面积
      • ConvexPolygonGravityCenter 凸多边形重心
      • NearestNeighbor 最近点对
    • Section-2 ConvexHull 第2节 凸包
      • GrahamScan Graham扫描算法
      • QuickHull 快速凸包算法
      • RotatingCalipers 旋转卡壳
  • Chapter-11 PatternMatch 第11章 文本匹配
    • SimpleMatch 简单匹配
    • AhoCorasickAutomata AC自动机
    • KnuthMorrisPratt KMP匹配算法
    • RabinKarp RabinKarp算法
    • BoyerMoore BoyerMoore算法
  • Chapter-12 GameTheory 第12章 博弈论
    • BashGame 巴什博弈
    • WythoffGame 威佐夫博弈
    • NimGame 尼姆博弈
Powered by GitBook
On this page
  • 问题
  • Ford–Fulkerson方法
  • Edmonds-Karp算法
  • Introduction To Algorithms
  • 源码
  • 测试
  1. Chapter-6 GraphTheory 第6章 图论
  2. Section-5 NetworkFlow 第5节 网络流

EdmondsKarp EdmondsKarp算法(最短路径增广算法)

问题

用Edmond Karp算法求网络G=<V,E>G = <V,E>G=<V,E>的最大流,GGG是单源点、单汇点,边的容量都为正整数的网络。

Ford–Fulkerson方法

Ford-Fulkerson方法是用于求解最大流的方法(并非算法),它通过寻找增广路径(Argumenting Path)来求最大流,但具体寻找的方法有多种算法实现。

网络流中边eu,ve_{u,v}eu,v​的剩余容量(Residual Capacity)是:

cf(u,v)=c(u,v)−f(u,v)c_f (u,v) = c(u,v) - f(u,v)cf​(u,v)=c(u,v)−f(u,v)

边的剩余容量定义了剩余网络(Residual Network)Gf=<V,Ef>G_f = <V, E_f>Gf​=<V,Ef​>,表示该网络的可用容量。

网络中的增广路径是剩余网络中的一条路径p=[v1,v2,…,vn]p = [v_1, v_2, \dots, v_n]p=[v1​,v2​,…,vn​],其中v1v_1v1​是源点sss,vnv_nvn​是汇点ttt,且其中每条边ei,je_{i,j}ei,j​(两端点为vi,vjv_i, v_jvi​,vj​)的剩余容量都满足cf(i,j)>0c_f(i,j) \gt 0cf​(i,j)>0,其中i,j∈[1,n]i, j \in [1, n]i,j∈[1,n]。

Ford-Fulkerson方法的主要过程如下:

(1)(1)(1) 初始时将网络GGG看作一个未被使用的原始剩余网络,该网络的最大流初始化为flowmax=0flow_{max} = 0flowmax​=0;

(2)(2)(2) 尝试从当前剩余网络中找到一条增广路径,该路径经过的所有边的最小的剩余容量Δ=min{c(i,j)−f(i,j)}\Delta = min \{ c(i,j) - f(i,j) \}Δ=min{c(i,j)−f(i,j)}即为这条流可用的容量(类似木桶短板原理)。这条增广路径使最大流的值增大为

flowmax=flowmax+Δflow_{max} = flow_{max} + \Deltaflowmax​=flowmax​+Δ

更新该路径上每条边ei,je_{i,j}ei,j​的剩余容量(满足反对称性)

f(i,j)=f(i,j)+Δf(j,i)=f(j,i)−Δcf(i,j)=cf(i,j)−Δcf(j,i)=cf(j,i)+Δ\begin{matrix} f(i,j) = f(i,j) + \Delta \\ f(j,i) = f(j,i) - \Delta \\ c_f(i,j) = c_f(i,j) - \Delta \\ c_f(j,i) = c_f(j,i) + \Delta \end{matrix}f(i,j)=f(i,j)+Δf(j,i)=f(j,i)−Δcf​(i,j)=cf​(i,j)−Δcf​(j,i)=cf​(j,i)+Δ​

(3)(3)(3) 重复第(2)(2)(2)步直到无法找出更多的增广路径,算法结束。flowmaxflow_{max}flowmax​为该网络的最大流;

Edmonds-Karp算法

Edmonds-Karp算法是Ford-Fulkerson方法的一种经典实现。通过BFS算法找出一条增广路径从源点sss到达汇点ttt。

设c(i,j)c(i,j)c(i,j)表示节点viv_ivi​到vjv_jvj​的边ei,je_{i,j}ei,j​的容量,cf(i,j)c_f(i,j)cf​(i,j)表示边ei,je_{i,j}ei,j​的剩余容量,逆向指针from(j)=ifrom(j) = ifrom(j)=i表示BFS搜索中从节点viv_ivi​搜索到邻节点vjv_jvj​(或者说节点vjv_jvj​是从节点viv_ivi​来的)。按照以下步骤进行BFS搜索增广路径:

(1)(1)(1) 初始时设置空队列queuequeuequeue,设置任意节点viv_ivi​的from(i)=nilfrom(i) = nilfrom(i)=nil(表示BFS搜索未开始),最大流flowmax=0flow_{max} = 0flowmax​=0,所有边的容量与其剩余容量相等c(i,j)=cf(i,j)c(i,j) = c_f(i,j)c(i,j)=cf​(i,j),边上的流为f(i,j)=f(j,i)=0f(i,j) = f(j,i) = 0f(i,j)=f(j,i)=0,将源点sss加入队列中并染红;

(2)(2)(2) 当queuequeuequeue不为空时,从中取出头节点viv_ivi​,若vi=tv_i = tvi​=t则已经找到一条增广路径;若vi≠tv_i \neq tvi​=t则遍历其所有邻节点找出所有的未被染红且剩余容量cf(i,j)>0c_f(i,j) \gt 0cf​(i,j)>0的邻节点vjv_jvj​(在剩余网络中进行BFS搜索),将其加入队列queuequeuequeue中,染红,并设置逆向指针from(j)=ifrom(j) = ifrom(j)=i。这样重复,若最终搜索到汇点ttt则找到一条增广路径,沿着逆向指针可以得到该增广路径上的所有边;若直到队列queuequeuequeue为空也没有搜索到汇点ttt则说明无法再找到更多的增广路径;

(3)(3)(3) 重复第(2)(2)(2)步,每找到一条增广路径,该路径中边的最小剩余容量Δ=min{c(i,j)−f(i,j)}\Delta = min \{ c(i,j) - f(i,j) \}Δ=min{c(i,j)−f(i,j)}即为该增广路径可用的流(Dinic算法中称为阻塞流BlockingFlowBlocking FlowBlockingFlow,即路径中的瓶颈)。更新该路径上所有边的剩余容量:

f(i,j)=f(i,j)+Δf(j,i)=f(j,i)−Δcf(i,j)=cf(i,j)−Δcf(j,i)=cf(j,i)+Δ\begin{matrix} f(i,j) = f(i,j) + \Delta \\ f(j,i) = f(j,i) - \Delta \\ c_f(i,j) = c_f(i,j) - \Delta \\ c_f(j,i) = c_f(j,i) + \Delta \end{matrix}f(i,j)=f(i,j)+Δf(j,i)=f(j,i)−Δcf​(i,j)=cf​(i,j)−Δcf​(j,i)=cf​(j,i)+Δ​

更新最大流

flowmax=flowmax+Δflow_{max} = flow_{max} + \Deltaflowmax​=flowmax​+Δ

当无法找出更多增广路径时算法结束,flowmaxflow_{max}flowmax​即为该网络的最大流;

下图演示了一条增广路径的搜索过程,其中源点为000汇点为888:

上图中的红线是BFS搜索剩余网络中节点的顺序,蓝线是从汇点沿着逆向指针回到源点的路径。

上图是本次BFS搜索的逆向指针。可得增广路径为[0,1,7,8][0, 1, 7, 8][0,1,7,8],其中边e0,1=3e_{0,1} = 3e0,1​=3是剩余容量最小的边,此条增广路径可用的流为333。

然后对该增广路径上的所有边更新剩余容量,下图中每条边上的数字x/yx / yx/y表示边上的流为xxx,边的容量为yyy,剩余容量为y−xy - xy−x,其中标记为红色的边的剩余容量为000:

可以发现,每次找出一条增广路径后,剩余网络中至少有一条边的剩余容量变为000,上图中边e0,1e_{0,1}e0,1​的剩余容量cf(0,1)=0c_f(0,1) = 0cf​(0,1)=0。

重复进行BFS搜索寻找增广路径,直到无法找出更多的增广路径时,算法结束。如下图所示:

该算法时间复杂度为O(∣V∣⋅∣E∣2)O(\lvert V \rvert \cdot \lvert E \rvert ^2)O(∣V∣⋅∣E∣2)。

Introduction To Algorithms

源码

测试

PreviousSection-5 NetworkFlow 第5节 网络流NextPushRelabel 压入与重标记算法

Last updated 6 years ago

VI.Graph Algorithms - 26.Maximum Flow - 26.2.The-Ford-Fulkerson method
EdmondsKarp.h
EdmondsKarp.cpp
EdmondsKarpTest.cpp
EdmondsKarp1.png
EdmondsKarp2.png
EdmondsKarp3.png
EdmondsKarp4.png