上下界最大流模板

虽然不知道为什么……

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;
			}
	}
}
posted @ 2011-07-16 23:05  zxfx100  阅读(271)  评论(0编辑  收藏  举报