最大流算法全解析:从Ford-Fulkerson到Dinic,实战代码与原理详解
目录引入Ford-Fulkerson算法Edmonds-Karp 算法Dinic算法最大流最小割定理练习摘要本文系统介绍了最大流算法的核心概念与经典实现。首先通过物流配送网络的实际案例引入流网络模型阐述容量限制与流量守恒两大基本性质。随后详细解析了三种主流算法Ford-Fulkerson 算法基于深度优先搜索与残存网络构建反向边的增广路径思想Edmonds-Karp 算法通过广度优先搜索确保每次找到最短增广路径提升稳定性Dinic 算法结合 BFS 分层与 DFS 多路增广并引入当前弧优化显著提高效率。文章还从数学角度证明了流叠加引理并阐述了最大流最小割定理的工程意义。最后提供了完整的 C 语言实现代码链式前向星存储及一系列经典练习题为读者构建了从理论到实践的知识体系。引入配送网络采用 “中心仓 — 中转场 — 末端站点” 三级结构所有包裹从龙华中心分拣仓发出经城市中转场集散后配送至各区末端站点。每条运输线路受道路通行能力、货运班次限制存在单日最大运力上限。运营团队需在 618 大促前测算全网单日最大可配送包裹总量并定位运力瓶颈以制定备货与调度方案。源点 S龙华中心分拣仓一级中转节点A - 深圳北站中转场、B - 平湖分拣中心二级中转节点C - 银湖中转场、D - 西丽中转场末端汇点E - 南山配送站、F - 福田配送站、G - 罗湖配送站SA12SB10AC8AD9BC6BG7CF11CG5DE10DF4构建网络流。流必须要满足两个条件1容量限制。对于所有的结点要求2流量守恒。对于所有的结点要求从点A流出的流量不能超过x从点A流出多少点B就能接收多少。流的值Ford-Fulkerson算法为了解决这样的问题先尝试使用深度搜索算法从源点到汇点找出一条路径更新容量再找出一条路径重复这种操作直到无法找到路径。在更新容量的时候先尝试用原容量减去流量。很快我们发现了问题dfs寻找的路径一开始可能不是朝着最大流方向寻找的导致最大流求解错误。下图的流网络中第一次dfs后更新容量发现无法继续找到路径最大流为10但实际上最大流为20。有什么方法可以让dfs迷途知返呢当流发生更新时流中所有的路径段容量减去流的值同时构建反向边反向边的容量为流的值。这种存在反向边的网络可以称作残存网络。在残存网络中找从源点到汇点的路径就是找增广路径。我们可以发现流之间相互叠加最终构成了最大流。我们想通过数学的方式证明这一点。设为一个流网络源结点为汇点为设为中的一个流。设由流所诱导的残存网络设为中的一个流。其值为。下面引用《算法导论第三版》26.1流网络中的证明方式证明容量守恒又证明流量守恒定义为有边从源结点s到达的结点集合为有边通往s的结点集合。我们有并且因为不允许有反平行边我们有。现在来计算将v的范围全部扩展到结点集合V上有补充。增广路径为在残存网络中从源点 s 到汇点 t 的简单路径顶点不重复路径上所有边残量 0。如下图所示S为起点T为终点各段路径默认流量非0红色箭头组成路径为增广路径的是选B选项。选项A存在回路选项C存在残量为0的边选项D存在顶点重复。下面走一遍Ford-Fulkerson算法。s为源点t为汇点最大流为20。示例代码C语言、链式前向星#include stdio.h #include string.h #include stdbool.h #define MAX_VEX 100 // 最大顶点数 #define MAX_EDGE 1000 // 最大边数量正向反向边 #define INF 99999999 // 代表无穷大 // ---------- 链式前向星结构 ---------- int head[MAX_VEX]; // head[u]u节点第一条边下标 int to[MAX_EDGE]; // 边的终点 int next[MAX_EDGE]; // 下一条边 int cap[MAX_EDGE]; // 边残量 int edge_cnt; // 边计数器 // 添加边正向边 反向边残量初始0 void add_edge(int u, int v, int c) { to[edge_cnt] v; cap[edge_cnt] c; next[edge_cnt] head[u]; head[u] edge_cnt; to[edge_cnt] u; cap[edge_cnt] 0; next[edge_cnt] head[v]; head[v] edge_cnt; } bool visited[MAX_VEX]; // DFS 访问标记 /* DFS 寻找一条从 u 到 t 的增广路径 u: 当前顶点, t: 汇点, f: 流入 u 的流量上限 返回值: 找到的增广路径上的瓶颈流量 */ int dfs(int u, int t, int f) { if (u t) return f; visited[u] true; for (int e head[u]; e ! -1; e next[e]) { int v to[e]; if (!visited[v] cap[e] 0) { int bottleneck dfs(v, t, f cap[e] ? f : cap[e]); if (bottleneck gt; 0) { cap[e] - bottleneck; cap[e ^ 1] bottleneck; return bottleneck; } } } return 0; } /* Ford-Fulkerson 主算法 */ int ford_fulkerson(int s, int t) { int max_flow 0; int augment; // 逗号表达式先清空访问标记再找增广路找到增广路则进入循环累加 while (memset(visited, 0, sizeof(visited)), (augment dfs(s, t, INF)) 0) { max_flow augment; } return max_flow; } // ---------- 测试 ---------- int main() { memset(head, -1, sizeof(head)); edge_cnt 0; int s 0, v1 1, v2 2, v3 3, v4 4, t 5; add_edge(s, v1, 16); add_edge(s, v2, 13); add_edge(v1, v3, 12); add_edge(v2, v1, 4); add_edge(v2, v4, 14); add_edge(v3, v2, 9); add_edge(v3, t, 20); add_edge(v4, v3, 7); add_edge(v4, t, 4); int result ford_fulkerson(s, t); printf(最大流 Max Flow %d\n, result); // 输出 23 return 0; }Edmonds-Karp 算法FF算法在寻找增广路径的时候喜欢四处跑时间不可控。如果将DFS替换为BFS相对来说会稳定很多。示例代码C语言、链式前向星#include stdio.h #include string.h #include stdbool.h #define MAX_VEX 100 #define MAX_EDGE 1000 #define INF 99999999 // ---------- 链式前向星 ---------- int head[MAX_VEX]; int to[MAX_EDGE]; int next[MAX_EDGE]; int cap[MAX_EDGE]; int edge_cnt; // 添加正向边 反向边 void add_edge(int u, int v, int c) { to[edge_cnt] v; cap[edge_cnt] c; next[edge_cnt] head[u]; head[u] edge_cnt; to[edge_cnt] u; cap[edge_cnt] 0; next[edge_cnt] head[v]; head[v] edge_cnt; } // BFS记录前驱parent[v] (from节点, 边编号) int parent_node[MAX_VEX]; int parent_edge[MAX_VEX]; int n; // 顶点数 /* BFS 在残量网络中寻找一条从 s 到 t 的最短增广路径 返回值true 表示找到路径false 表示无路可走 */ bool bfs(int s, int t) { memset(parent_node, -1, sizeof(parent_node)); memset(parent_edge, -1, sizeof(parent_edge)); int queue[MAX_VEX]; int front 0, rear 0; queue[rear] s; parent_node[s] s; // 源点标记 while (front rear) { int u queue[front]; // 遍历u所有出边 for (int e head[u]; e ! -1; e next[e]) { int v to[e]; // 残量0 且未访问 if (parent_node[v] -1 cap[e] 0) { parent_node[v] u; parent_edge[v] e; // 记录到达v使用的边 if (v t) return true; queue[rear] v; } } } return false; } /* Edmonds-Karp 主算法 */ int edmonds_karp(int s, int t) { int max_flow 0; // 核心循环只要 BFS 能找到增广路径 while (bfs(s, t)) { // 1. 寻找瓶颈路径上的最小残量 int bottleneck INF; for (int v t; v ! s; v parent_node[v]) { int e parent_edge[v]; if (cap[e] bottleneck) { bottleneck cap[e]; } } // 2. 更新残量网络 for (int v t; v ! s; v parent_node[v]) { int e parent_edge[v]; cap[e] - bottleneck; // 正向边容量减少 cap[e ^ 1] bottleneck; // 反向边容量增加异或取反向边 } // 3. 累加最大流 max_flow bottleneck; } return max_flow; } // ---------- 测试 ---------- int main() { memset(head, -1, sizeof(head)); edge_cnt 0; int s 0, v1 1, v2 2, v3 3, v4 4, t 5; n 6; // 用到最大节点编号5总共6个节点0~5 // 建图 add_edge(s, v1, 16); // S -gt; v1 add_edge(s, v2, 13); // S -gt; v2 add_edge(v1, v3, 12); // v1 -gt; v3 add_edge(v2, v1, 4); // v2 -gt; v1 add_edge(v2, v4, 14); // v2 -gt; v4 add_edge(v3, v2, 9); // v3 -gt; v2 add_edge(v3, t, 20); // v3 -gt; t add_edge(v4, v3, 7); // v4 -gt; v3 add_edge(v4, t, 4); // v4 -gt; t int result edmonds_karp(s, t); printf(Edmonds-Karp 最大流结果: %d\n, result); // 标准答案 23 return 0; }Dinic算法EK算法找到汇点后立刻返回一条增广路然后重新DFS如果能多路增广效率就会提升很多。DFS的工作职责不再是找增广路径而是为残存网络分层分层后再通过DFS找增广路径。弧优化在朴素 Dinic 的 DFS 增广过程中每次访问一个节点时都会从头遍历该节点的所有邻接边。但在同一轮 BFS 分层周期内很多边已经失去了增广价值边的剩余容量已经耗尽无法再通过流量从这条边出发后续路径根本无法到达汇点。示例代码C语言、链式前向星#include stdio.h #include string.h #include stdbool.h #define MAXN 10005 // 最大顶点数 #define MAXM 200005 // 最大边数包含反向边 #define INF 0x3f3f3f3f // ---------- 链式前向星数据结构 ---------- int head[MAXN]; int to[MAXM]; int next[MAXM]; int cap[MAXM]; int edge_cnt; void add_edge(int u, int v, int c) { // 正向边 to[edge_cnt] v; cap[edge_cnt] c; next[edge_cnt] head[u]; head[u] edge_cnt; // 反向边初始容量为0用于退流 to[edge_cnt] u; cap[edge_cnt] 0; next[edge_cnt] head[v]; head[v] edge_cnt; } // ---------- Dinic 算法核心变量 ---------- int level[MAXN]; // 节点层次 int cur[MAXN]; // 当前弧优化指针 int queue[MAXN]; // BFS 手写队列 int n; // 总节点数 // BFS 构建分层图 bool bfs(int s, int t) { memset(level, -1, sizeof(int) * n); int front 0, rear 0; level[s] 0; queue[rear] s; while (front lt; rear) { int u queue[front]; for (int e head[u]; e ! -1; e next[e]) { int v to[e]; if (cap[e] gt; 0 amp;amp; level[v] -1) { level[v] level[u] 1; queue[rear] v; } } } return level[t] ! -1; } // DFS 多路增广一次调用推完所有可行增广路返回从u出发的总推送流量 int dfs(int u, int t, int flow) { if (u t || flow 0) return flow; int total_push 0; // 累计从当前节点推送出去的总流量 // 从当前弧开始遍历流量耗尽则提前退出 for (int *e_ptr amp;cur[u]; *e_ptr ! -1 amp;amp; flow gt; 0; *e_ptr next[*e_ptr]) { int v to[*e_ptr]; if (cap[*e_ptr] gt; 0 amp;amp; level[v] level[u] 1) { int bottleneck dfs(v, t, flow lt; cap[*e_ptr] ? flow : cap[*e_ptr]); if (bottleneck gt; 0) { // 更新残量网络 cap[*e_ptr] - bottleneck; cap[(*e_ptr) ^ 1] bottleneck; total_push bottleneck; flow - bottleneck; // 剩余可推送流量减少 } } } return total_push; } // Dinic 主算法 int dinic(int s, int t) { int max_flow 0; while (bfs(s, t)) { // 每轮分层后重置当前弧 for (int i 0; i lt; n; i) cur[i] head[i]; // 一次DFS求出本轮阻塞流直接累加 max_flow dfs(s, t, INF); } return max_flow; } // ---------- 测试 ---------- int main() { memset(head, -1, sizeof(head)); edge_cnt 0; int s 0, v1 1, v2 2, v3 3, v4 4, t 5; n 6; // 建图 add_edge(s, v1, 16); add_edge(s, v2, 13); add_edge(v1, v3, 12); add_edge(v2, v1, 4); add_edge(v2, v4, 14); add_edge(v3, v2, 9); add_edge(v3, t, 20); add_edge(v4, v3, 7); add_edge(v4, t, 4); int result dinic(s, t); printf(Dinic 最大流结果: %d\n, result); return 0; }最大流最小割定理对于一个有源点 s、汇点 t 的有向流网络若将顶点全集 V 划分为两个互不相交的子集 S 和 T满足源点在源侧汇点在汇侧划分完整则这个二元组就称为该网络的一个s-t 割。流网络G中任意流f的值不能超过G的任意切割的容量。在下图中最大流的值为23最小割的值也为23红箭头。在工程中找到最小割提升效率可以缩短工期。练习洛谷 P3376 【模板】网络最大流AcWing 2171. EK 求最大流洛谷 P2756 飞行员配对方案问题AcWing 2240. 餐饮Dining洛谷 P2764 最小路径覆盖问题洛谷 P1344 【模板】最小割AcWing 2234. 多源汇最大流洛谷 P2774 方格取数问题LeetCode LCP 04. 覆盖洛谷 P2057 [SHOI2007] 善意的投票

相关新闻

杰理 AW31N 怎么烧录?多种程序烧录方式详解21

杰理 AW31N 怎么烧录?多种程序烧录方式详解21

简介AW31N属于杰理AIOT系列芯片,2024年发布进入市场,开发模式基于杰理的软件开放平台二次开发,上手之前需要先熟悉平台的框架、各种API接口,这一块没什么文档说明,对新手不太友好。今天主要分享杰理AW31N程序烧录有哪几…

2026/8/10 11:53:44 阅读更多 →
3个理由告诉你为什么HEIF Utility仍然是Windows用户处理苹果照片的最佳选择

3个理由告诉你为什么HEIF Utility仍然是Windows用户处理苹果照片的最佳选择

3个理由告诉你为什么HEIF Utility仍然是Windows用户处理苹果照片的最佳选择 【免费下载链接】HEIF-Utility HEIF Utility - View/Convert Apple HEIF images on Windows. 项目地址: https://gitcode.com/gh_mirrors/he/HEIF-Utility 在Windows平台上查看和转换iPhone拍摄…

2026/8/10 11:53:44 阅读更多 →
Claude导出word手机 ,我只认“AI 导出鸭”

Claude导出word手机 ,我只认“AI 导出鸭”

Claude导出word手机 ,我只认“AI 导出鸭” Claude 在手机网页版生成的内容堪称艺术品——逻辑缜密的分析框架、排版考究的数据表格、甚至包含 Mermaid 时序图的系统设计说明。但当你想把这些内容导出为 Word 文档发给客户时,艺术品就变成了“碎纸机里的拼…

2026/8/10 11:53:44 阅读更多 →

最新新闻

DELETE语句详解:从基础语法到生产实践

DELETE语句详解:从基础语法到生产实践

1. 为什么DELETE语句值得专门学习在数据库操作中,DELETE语句看似简单,实则暗藏玄机。作为数据操作的"最后一道防线",它直接决定了数据的生死存亡。我见过太多因为不当DELETE操作导致的生产事故——从误删用户订单到清空核心配置表&…

2026/8/10 12:51:38 阅读更多 →
ComfyUI-Impact-Pack V8:解锁AI图像增强的终极解决方案

ComfyUI-Impact-Pack V8:解锁AI图像增强的终极解决方案

ComfyUI-Impact-Pack V8:解锁AI图像增强的终极解决方案 【免费下载链接】ComfyUI-Impact-Pack Custom nodes pack for ComfyUI This custom node helps to conveniently enhance images through Detector, Detailer, Upscaler, Pipe, and more. 项目地址: https:/…

2026/8/10 12:51:38 阅读更多 →
销售总表按产品线拆分,从2小时到5分钟:制造业研发的真实效率革命 —— 企业级智能自动化技术重构人机协同范式

销售总表按产品线拆分,从2小时到5分钟:制造业研发的真实效率革命 —— 企业级智能自动化技术重构人机协同范式

在制造业数字化转型的深水区,一场围绕研发与生产效率的“时间革命”正在全面展开。随着人工智能技术从虚拟世界走向现实物理世界,制造业的核心竞争逻辑已发生根本性改变:从过去单纯追求规模经济与成本优势,转向追求以“迭代速度”…

2026/8/10 12:51:38 阅读更多 →
AI Agent 面试题 460:如何评估Agent自我纠错的有效性?

AI Agent 面试题 460:如何评估Agent自我纠错的有效性?

🔥 AI Agent 面试题 460:如何评估Agent自我纠错的有效性?摘要:本文深入解析了「如何评估Agent自我纠错的有效性?」这一 AI Agent 领域的核心面试题。文章从 自我反思与纠错 的基本概念出发,系统性地剖析了 …

2026/8/10 12:51:38 阅读更多 →
AI Agent 面试题 457:Agent的自我批评(Self-Critique)机制有哪些实现方式?

AI Agent 面试题 457:Agent的自我批评(Self-Critique)机制有哪些实现方式?

🔥 AI Agent 面试题 457:Agent的自我批评(Self-Critique)机制有哪些实现方式?摘要:本文深入解析了「Agent的自我批评(Self-Critique)机制有哪些实现方式?」这一 AI Agent…

2026/8/10 12:51:38 阅读更多 →
终极Windows和Office激活解决方案:KMS_VL_ALL_AIO智能激活工具完整指南

终极Windows和Office激活解决方案:KMS_VL_ALL_AIO智能激活工具完整指南

终极Windows和Office激活解决方案:KMS_VL_ALL_AIO智能激活工具完整指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows系统激活弹窗而烦恼吗?或者因为Offi…

2026/8/10 12:50:38 阅读更多 →

日新闻

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南 【免费下载链接】graphql-css A blazing fast CSS-in-GQL™ library. 项目地址: https://gitcode.com/gh_mirrors/gr/graphql-css GraphQL-CSS是一个基于GraphQL的CSS-in-GQL™库&#xff0…

2026/8/10 0:00:02 阅读更多 →
告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南 【免费下载链接】kiss-translator A simple, open source bilingual translation extension & Greasemonkey script (一个简约、开源的 双语对照翻译扩展 & 油猴脚本) 项目地址: https://gitcode.com/…

2026/8/10 0:00:02 阅读更多 →
BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案 【免费下载链接】BepInEx.ConfigurationManager Plugin configuration manager for BepInEx 项目地址: https://gitcode.com/gh_mirrors/be/BepInEx.ConfigurationManager 你是否曾经因为游戏插件的复杂…

2026/8/10 0:00:02 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/10 1:05:29 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/10 1:05:29 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/10 1:05:29 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/9 17:05:02 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/10 1:05:29 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/9 17:05:02 阅读更多 →