Dinic+当前弧优化 O(n^2m)
链式前向星的下标要从偶数开始,head初始化为-1
const int N = 105;
struct edge { int to, next, flow; }e[N*N*2];
int cnt, head[N];
namespace MaxFlow
{
int cur[N], depth[N];
int dfs(int u, int flow, int T)
{
if (u == T) return flow;
for (int &i = cur[u]; ~i; i = e[i].next)
{
int v = e[i].to;
if (depth[v] == depth[u] + 1 && e[i].flow)
{
int d = dfs(v, min(flow, e[i].flow), T);
if (d)
{
e[i].flow -= d;
e[i ^ 1].flow += d;
return d;
}
}
}
return 0;
}
bool bfs(int S, int T)
{
memset(depth, 0, sizeof(depth));
std::queue<int>q;
depth[S] = 1;
q.push(S);
while (!q.empty())
{
int u = q.front(); q.pop();
for (int i = head[u]; ~i; i = e[i].next)
{
int v = e[i].to;
if (!depth[v] && e[i].flow)
{
depth[v] = depth[u] + 1;
q.push(v);
}
}
}
return depth[T];
}
int Dinic(int S, int T)
{
int ans = 0;
while (bfs(S, T))
{
memcpy(cur, head, sizeof(head));
while (int d = dfs(S, 0xffffff, T))
ans += d;
}
return ans;
}
}
最小费用最大流
head初始化为0,边的编号要从偶数开始 一般取0
const int MAXN = 150;
struct Edge { int to, next, cost, flow; }e[MAXN*MAXN * 2];
int cnt, head[MAXN];
namespace MinCostFlow
{
int dis[MAXN], pre[MAXN];
bool vis[MAXN];
bool SPFA(int s, int t)
{
std::queue<int>q;
memset(dis, 127, sizeof(dis));
memset(vis, false, sizeof(vis));
memset(pre, -1, sizeof(pre));
dis[s] = 0;
vis[s] = true;
q.push(s);
while (!q.empty())
{
int u = q.front(); q.pop();
vis[u] = false;
for (int i = head[u]; i != -1; i = e[i].next)
{
int v = e[i].to;
if (dis[v] > dis[u] + e[i].cost && e[i].flow > 0)
{
dis[v] = dis[u] + e[i].cost;
pre[v] = i;
if (!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
return pre[t] != -1;
}
void MCMF(int s, int t, int &cost, int &flow)
{
cost = flow = 0;
while (SPFA(s, t))
{
int Min = 1 << 30;
for (int i = pre[t]; i != -1; i = pre[e[i ^ 1].to])
Min = std::min(Min, e[i].flow);
for (int i = pre[t]; i != -1; i = pre[e[i ^ 1].to])
{
e[i].flow -= Min;
e[i ^ 1].flow += Min;
cost += e[i].cost * Min;
}
flow += Min;
}
}
}