#include <iostream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
// 边的数据结构
struct Edge {
int from, to, capacity, flow;
};
// Dinic 算法类
class Dinic {
private:
int n; // 图中节点的数量
vector<vector<int>> adj; // 邻接表,存储图的结构
vector<Edge> edges; // 存储所有边的信息
vector<int> dist; // 存储节点的层级距离
vector<int> ptr; // 指针,标记从每个节点开始查找增广路径时遍历到的边的位置
// 利用 BFS 构建分层图
bool buildLevelGraph(int source, int sink) {
fill(dist.begin(), dist.end(), -1); // 初始化节点的层级距离为-1
queue<int> q;
q.push(source);
dist[source] = 0; // 源节点的层级距离为0
while (!q.empty()) {
int curr = q.front();
q.pop();
for (int i = 0; i < adj[curr].size(); i++) {
int edgeIdx = adj[curr][i]; // 当前边在 edges 中的索引
Edge& e = edges[edgeIdx];
if (dist[e.to] == -1 && e.flow < e.capacity) {
// 当前边的终点未标记层级且还可以增加流量,则加入分层图
dist[e.to] = dist[curr] + 1;
q.push(e.to);
}
}
}
return (dist[sink] != -1); // 若汇节点的层级距离不为-1,则存在增广路径
}
// 在分层图上寻找增广路径,并增加流量
int findAugmentingPath(int curr, int sink, int minCapacity) {
if (curr == sink)
return minCapacity; // 到达汇节点,返回流量增加的最小值
while (ptr[curr] < adj[curr].size()) {
int edgeIdx = adj[curr][ptr[curr]]; // 当前边在 edges 中的索引
Edge& e = edges[edgeIdx];
if (dist[e.to] == dist[curr] + 1 && e.flow < e.capacity) {
// 下一个节点的层级等于当前节点层级+1,并且当前边还可以增加流量
int bottleneck = findAugmentingPath(e.to, sink, min(minCapacity, e.capacity - e.flow));
if (bottleneck > 0) {
// 更新当前边的流量和反向边的流量
e.flow += bottleneck;
edges[edgeIdx ^ 1].flow -= bottleneck;
return bottleneck;
}
}
ptr[curr]++;
}
return 0; // 没有找到增广路径,返回0
}
public:
Dinic(int numNodes) {
n = numNodes;
adj.resize(n);
dist.resize(n);
ptr.resize(n);
}
// 添加一条边到图中
void addEdge(int from, int to, int capacity) {
// 正向边
edges.push_back({from, to, capacity, 0});
adj[from].push_back(edges.size() - 1);
// 反向边,流量为0,容量为0
edges.push_back({to, from, 0, 0});
adj[to].push_back(edges.size() - 1);
}
// 计算最大流
int maxFlow(int source, int sink) {
int totalFlow = 0;
while (buildLevelGraph(source, sink)) {
fill(ptr.begin(), ptr.end(), 0); // 初始化指针 ptr
while (int bottleneck = findAugmentingPath(source, sink, INT_MAX)) {
totalFlow += bottleneck;
}
}
return totalFlow;
}
};
int main() {
int numNodes = 4; // 图中节点的数量
Dinic dinic(numNodes);
// 添加边到图中
dinic.addEdge(0, 1, 3);
dinic.addEdge(0, 2, 2);
dinic.addEdge(1, 2, 2);
dinic.addEdge(1, 3, 3);
dinic.addEdge(2, 3, 3);
int source = 0; // 源节点
int sink = 3; // 汇节点
int maxFlow = dinic.maxFlow(source, sink);
cout << "Maximum flow: " << maxFlow << endl;
return 0;
}
同时可以参考 博客 https://www.cnblogs.com/SYCstudio/p/7260613.html的讲解