上下界最大流模板

虽然不知道为什么……

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;

			}

	}

}

你可能感兴趣的:(最大流)