对于每条边加了个下界限制B(e),这样每条边需满足条件B(e) <= F(e) <= C(e)。
1)对于无源点和汇点
对于每一条边e,将其分离成两条边e’和e’’,其中的容量C(e’) = C(e) - B(e),C(e’’) = B(e)
这样分离后只需要e’'满流即可
步骤:新建源点S和汇点T,对原图的每一条边e = <u, v>,建立从u到v容量C(e) - B(e)的弧,从u到T,S到v分别建立一条容量为B(e)的弧。求一边新网络的最大流
2)对有源点和汇点
只需要先将转换为无源点和汇点的网络,将汇点建立一条容量为无穷大的边到源点
普通网络流板子
#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read()
{
int k = 0, flag = 1;
char c;
c = getchar();
if (c == '-')
flag = 0, c = getchar();
while (!isdigit(c))
c = getchar();
while (isdigit(c))
{
k = (k << 3) + (k << 1) + c - '0';
c = getchar();
}
return flag ? k : -k;
}
const int maxn = 1e4 + 10;
const int INF = 0x3f3f3f3f;
struct Edge
{
int from, to, cap, flow;
Edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {}
};
struct EdmondKarp
{
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
int a[maxn], p[maxn];
void init(int n)
{
for (register int i = 0; i < n; i++)
G[i].clear();
edges.clear();
}
void AddEdge(int from, int to, int cap)
{
edges.push_back(Edge(from, to, cap, 0));
edges.push_back(Edge(to, from, 0, 0));
m = edges.size();
G[from].push_back(m - 2);
G[to].push_back(m - 1);
}
int Maxflow(int s, int t)
{
int flow = 0;
for (;;)
{
memset(a, 0, sizeof(a));
queue<int> Q;
Q.push(s);
a[s] = INF;
while (!Q.empty())
{
int x = Q.front();
Q.pop();
for (register int i = 0; i < G[x].size(); i++)
{
Edge &e = edges[G[x][i]];
if (!a[e.to] && e.cap > e.flow)
{
p[e.to] = G[x][i];
a[e.to] = min(a[x], e.cap - e.flow);
Q.push(e.to);
}
}
if (a[t])
break;
}
if (!a[t])
break;
for (int u = t; u != s; u = edges[p[u]].from)
{
edges[p[u]].flow += a[t];
edges[p[u] ^ 1].flow -= a[t];
}
flow += a[t];
}
return flow;
}
};
int main()
{
EdmondKarp ek;
// ek.init(n); 点的数量
// ek.AddEdge(0, i, 1); 加边
// cout << ek.Maxflow(s, t);
}