在网络优化、交通调度、任务分配等众多实际问题中,C++最大流算法扮演着至关重要的角色。本文将带你从零开始,一步步理解什么是最大流问题,并用C++实现两种经典算法:Edmonds-Karp 和 Dinic。即使你是编程小白,也能轻松上手!
想象一个供水系统:有一个水源(源点),一个水池(汇点),中间通过若干管道连接。每条管道都有一个最大流量限制。我们的目标是:在不超出任何管道容量的前提下,从源点向汇点输送尽可能多的水——这就是最大流问题。

Edmonds-Karp算法是 Ford-Fulkerson 方法的一种具体实现,它使用 BFS(广度优先搜索)来寻找增广路径,保证了时间复杂度为 O(V·E²),其中 V 是顶点数,E 是边数。
其核心思想是:不断在残量网络中找从源点到汇点的最短路径(按边数),并沿该路径增加流量,直到无法再找到增广路径为止。
#include <iostream>#include <vector>#include <queue>#include <climits>using namespace std;const int MAXN = 1005;int capacity[MAXN][MAXN];int parent[MAXN];bool visited[MAXN];bool bfs(int s, int t, int n) { fill(visited, visited + n, false); queue<int> q; q.push(s); visited[s] = true; parent[s] = -1; while (!q.empty()) { int u = q.front(); q.pop(); for (int v = 0; v < n; v++) { if (!visited[v] && capacity[u][v] > 0) { q.push(v); parent[v] = u; visited[v] = true; } } } return visited[t];}int edmondsKarp(int s, int t, int n) { int max_flow = 0; while (bfs(s, t, n)) { int path_flow = INT_MAX; for (int v = t; v != s; v = parent[v]) { int u = parent[v]; path_flow = min(path_flow, capacity[u][v]); } for (int v = t; v != s; v = parent[v]) { int u = parent[v]; capacity[u][v] -= path_flow; capacity[v][u] += path_flow; // 反向边 } max_flow += path_flow; } return max_flow;}int main() { int n = 6; // 节点数量 // 初始化容量矩阵(示例图) capacity[0][1] = 16; capacity[0][2] = 13; capacity[1][2] = 10; capacity[1][3] = 12; capacity[2][1] = 4; capacity[2][4] = 14; capacity[3][2] = 9; capacity[3][5] = 20; capacity[4][3] = 7; capacity[4][5] = 4; cout << "最大流为: " << edmondsKarp(0, 5, n) << endl; return 0;}
Dinic算法是一种更高效的网络流算法,尤其适用于稠密图。它通过构建分层图(Level Graph)并进行多次 DFS 阻塞流(Blocking Flow)计算,时间复杂度为 O(V²·E)。
Dinic 的优势在于:一次 BFS 构建层次后,可以进行多次 DFS 增广,避免了 Edmonds-Karp 中频繁 BFS 的开销。
#include <iostream>#include <vector>#include <queue>#include <climits>using namespace std;struct Edge { int to, rev, cap; Edge(int t, int r, int c) : to(t), rev(r), cap(c) {}};vector<vector<Edge>> graph;vector<int> level;void add_edge(int u, int v, int cap) { graph[u].emplace_back(v, graph[v].size(), cap); graph[v].emplace_back(u, graph[u].size() - 1, 0);}bool bfs(int s, int t) { fill(level.begin(), level.end(), -1); queue<int> q; q.push(s); level[s] = 0; while (!q.empty()) { int u = q.front(); q.pop(); for (auto& e : graph[u]) { if (e.cap > 0 && level[e.to] == -1) { level[e.to] = level[u] + 1; q.push(e.to); } } } return level[t] != -1;}int dfs(int u, int t, int flow) { if (u == t) return flow; for (auto& e : graph[u]) { if (e.cap > 0 && level[e.to] == level[u] + 1) { int f = dfs(e.to, t, min(flow, e.cap)); if (f > 0) { e.cap -= f; graph[e.to][e.rev].cap += f; return f; } } } return 0;}int dinic(int s, int t) { int max_flow = 0; while (bfs(s, t)) { int f; while ((f = dfs(s, t, INT_MAX)) > 0) { max_flow += f; } } return max_flow;}int main() { int n = 6; graph.resize(n); level.resize(n); add_edge(0, 1, 16); add_edge(0, 2, 13); add_edge(1, 2, 10); add_edge(1, 3, 12); add_edge(2, 1, 4); add_edge(2, 4, 14); add_edge(3, 2, 9); add_edge(3, 5, 20); add_edge(4, 3, 7); add_edge(4, 5, 4); cout << "Dinic算法求得的最大流: " << dinic(0, 5) << endl; return 0;}
通过本文,你已经掌握了C++最大流算法的基本原理与两种主流实现方式。无论是学习网络流算法理论,还是准备算法竞赛,这些知识都至关重要。建议你动手敲一遍代码,修改测试用例,加深理解。
记住:算法不是死记硬背,而是理解+实践。祝你在算法之路上越走越远!
本文由主机测评网于2025-12-15发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025127909.html