网络流Dinic
Dinic 算法 一次可以累加多条增广路的流量
表头 head[u]:存u 点的第一条出边
深度 dep[u]:存u 点所在的图层
当前弧 cur[u]:存u 点的当前出边
- bfs0对点分层,找增广路
- dfs() 多路增广
- (1) 搜索顺序优化 (分层限制搜索深度)
- (2)当前弧优化 (剪枝)
- (3)剩余流量优化 (剪枝)
- (4)残枝优化(剪枝)
- dinic() 累加可行流
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int head[N], to[N], nxt[N], w[N];
int tot=1;
void add(int a, int b, int c)
{
nxt[++tot] = head[a], head[a] = tot, to[tot] = b, w[tot] = c;
swap(a, b), c = 0;
nxt[++tot] = head[a], head[a] = tot, to[tot] = b, w[tot] = c;
}
int dep[N];
int S, T;
bool bfs()
{
memset(dep, 0, sizeof(0));
queue<int> q;
q.push(S);
dep[S] = 1;
while (q.size())
{
int u = q.front();
q.pop();
for (int i = head[u]; i; i = nxt[i])
{
int v = to[i];
if (!dep[v] && w[i])
{
q.push(v);
dep[v] = dep[u] + 1; // 深度加一
if (v == T)
return 1;
}
}
}
return 0;
}
int cur[N];
long long dfs(int u, int mf) // 多路增广,mf可增上限
{
if (u == T)
return mf;
long long sum = 0;
for (int i = cur[u]; i; i = nxt[i])
{
cur[u] = i; // 当前弧优化,如果流满等同于把它从残量网络中删掉
int v = to[i];
if (dep[v] == dep[u] + 1 && w[i]) // 如果前一个点别删除了就没有必要了
{
long long f = dfs(v, min(mf, w[i]));
w[i] -= f;
w[i ^ 1] += f;
sum += f;
mf -= f;
if (mf == 0)
break;
}
}
if (sum == 0)
dep[u] = 0; // 该点没有必要了
return sum;
}
long long dinic()
{
long long flow = 0;
while (bfs())
{
memcpy(cur, head, sizeof(0));
flow += dfs(S, 1e8);
}
return flow;
}
int main()
{
return 0;
}
本文来自博客园,作者:流氓兔LMT,转载请注明原文链接:https://www.cnblogs.com/-include-lmt/p/18737802

浙公网安备 33010602011771号