上下界最大流模板
虽然不知道为什么……
C++ code:
#include <iostream>
#include <cstdio>
#include <cstring>
#define MAXN 200
#define inf 1000000000
using namespace std;
int limit_max_flow(int, int [][MAXN], int [][MAXN], int, int, int [][MAXN]);
void _max_flow(int, int [][MAXN], int, int, int [][MAXN]);
int main()
{
int n, m, mat[200][200], bf[200][200], flow[200][200], i, k, j, ID, G, U, D, p, q;
while(scanf("%d%d", &n, &m) == 2)
{
memset(mat, 0, sizeof(mat));
memset(bf, 0, sizeof(bf));
memset(flow, 0, sizeof(flow));
for(i = 1; i <= n; i++)
{
scanf("%d", &k);
for(j = 1; j <= k; j++)
{
scanf("%d", &ID);
mat[n + ID][i] = 1;
}
}
for(i = 1; i <= m; i++)
{
scanf("%d", &U);
mat[0][n + i] = U;
}
for(i = 1; i <= m; i++)
{
scanf("%d", &D);
bf[0][n + i] = D;
}
scanf("%d", &G);
for(i = 1; i <= G; i++)
{
scanf("%d", &p);
for(j = 1; j <= p; j++)
{
scanf("%d", &q);
for(k = 1; k <= m; k++)
if(mat[n + k][q])
{
mat[n + k][q] = 0;
mat[n + k][n + m + i] = mat[n + m + i][q] = 1;
}
}
}
for(i = 1; i <= n; i++)
mat[i][n + m + G + 1] = 1;
printf("%d\n", limit_max_flow(n + m + G + 2, mat, bf, 0, n + m + G + 1, flow));
}
return 0;
}
int limit_max_flow(int n, int mat[][MAXN], int bf[][MAXN], int source, int sink, int flow[][MAXN])
{
int i, j, sk, ks;
if(source==sink)
return inf;
for(mat[n][n + 1] = mat[n + 1][n] = mat[n][n] = mat[n+1][n+1] = i = 0; i < n; i++)
for(mat[n][i] = mat[i][n] = mat[n + 1][i] = mat[i][n + 1] = j = 0; j < n; j++)
{
mat[i][j] -= bf[i][j];
mat[n][i] += bf[j][i];
mat[i][n + 1] += bf[i][j];
}
sk = mat[source][sink];
ks = mat[sink][source];
mat[source][sink] = mat[sink][source] = inf;
for(i = 0; i < n + 2; i++)
for(j = 0; j < n + 2; flow[i][j++] = 0);
_max_flow(n + 2, mat, n, n + 1, flow);
for(i = 0; i < n; i++)
if(flow[n][i] < mat[n][i])
return -1;
flow[source][sink] = flow[sink][source] = 0;
mat[source][sink] = sk;
mat[sink][source] = ks;
_max_flow(n, mat, source, sink, flow);
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
{
mat[i][j] += bf[i][j];
flow[i][j] += bf[i][j];
}
for(i = j = 0; i < n; j += flow[source][i++]);
return j;
}
void _max_flow(int n, int mat[][MAXN], int source, int sink, int flow[][MAXN])
{
int pre[MAXN], que[MAXN], d[MAXN], p, q, t, i, j;
for(;;)
{
for (i=0;i<n;pre[i++]=0);
pre[t = source] = source + 1;
d[t] = inf;
for(p = q = 0; p <= q && !pre[sink]; t = que[p++])
for(i = 0; i < n; i++)
if(!pre[i] && (j = mat[t][i] - flow[t][i]))
{
pre[que[q++] = i] = t + 1;
d[i] = d[t] < j ? d[t] : j;
}
else if(!pre[i] && (j = flow[i][t]))
{
pre[que[q++] = i] = -t - 1;
d[i] = d[t] < j ? d[t] : j;
}
if(!pre[sink])
break;
for(i = sink; i != source;)
if(pre[i] > 0)
{
flow[pre[i] - 1][i] += d[sink];
i = pre[i] - 1;
}
else
{
flow[i][-pre[i] - 1] -= d[sink];
i = -pre[i] - 1;
}
}
}

浙公网安备 33010602011771号