ACM模版
有上下界的最小(最大)流
const int inf = 0x3f3f3f3f;
const int N = 1010;
int up[N][N], low[N][N], flow[N][N];
int pv[N], que[N], d[N];
void maxflow(int n, int src, int sink)
{
int p, q, t, i, j;
do
{
for (i = 0; i < n; pv[i++] = 0);
pv[t = src] = src + 1;
d[t] = inf;
for (p = q = 0; p <= q && !pv[sink]; t = que[p++])
{
for (i = 0; i < n; i++)
{
if (!pv[i] && up[t][i] && (j = up[t][i] - flow[t][i]) > 0)
{
pv[que[q++] = i] = +t + 1, d[i] = d[t] < j ? d[t] : j;
}
else if (!pv[i] && up[i][t] && (j = flow[i][t]) > 0)
{
pv[que[q++] = i] = -t - 1, d[i] = d[t] < j ? d[t] : j;
}
}
}
for (i = sink; pv[i] && i != src;)
{
if (pv[i] > 0)
{
flow[pv[i] - 1][i] += d[sink], i = pv[i] - 1;
}
else
{
flow[i][-pv[i] - 1] -= d[sink], i = -pv[i] - 1;
}
}
}
while (pv[sink]);
return ;
}
int limitflow(int n, int src, int sink)
{
int i, j, sk, ks;
if (src == sink)
{
return inf;
}
up[n][n + 1] = up[n + 1][n] = up[n][n] = up[n + 1][n + 1] = 0;
for (i = 0; i < n; i++)
{
up[n][i] = up[i][n] = up[n+1][i] = up[i][n+1] = 0;
for (j = 0; j < n; j++)
{
up[i][j] -= low[i][j];
up[n][i] += low[j][i];
up[i][n + 1] += low[i][j];
}
}
sk = up[src][sink];
ks = up[sink][src];
up[src][sink] = up[sink][src] = inf;
maxflow(n + 2, n, n + 1);
for (i = 0; i < n; i++)
{
if (flow[n][i] < up[n][i])
{
return -1;
}
}
flow[src][sink] = flow[sink][src] = 0;
up[src][sink] = sk;
up[sink][src] = ks;
maxflow(n, sink, src);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
up[i][j] += low[i][j];
flow[i][j] += low[i][j];
}
}
for (j = i = 0; i < n; j += flow[src][i++]);
return j;
}