POJ3281 网络流 dining

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
using namespace std;


#define mxn 820
#define inf 0x3f3f3f3f
#define ll long long 
#define ull unsigned long long
#define eps 1e-8

int g[mxn][mxn], flow[mxn][mxn], a[mxn], q[mxn*mxn], p[mxn];
int head, tail;

int n, f, d;

int main() {
	scanf( "%d%d%d", &n, &f, &d );
	memset( g, 0, sizeof( g ) );
	int tot = f + 2 * n + d + 1;
	for( int i = 1; i <= n; ++i ) {
		g[f+i][f+n+i] = 1;
	}
	for( int i = 1; i <= f; ++i )
		g[0][i] = 1;
	for( int i = 1; i <= d; ++i ) 
		g[f+2*n+i][tot] = 1;
	for( int i = 1; i <= n; ++i ) {
		int _f, _d;
		scanf( "%d%d", &_f, &_d );
		int ff, dd;
		for( int j = 1; j <= _f; ++j ) {
			scanf( "%d", &ff );
			g[ff][i+f] = 1;
		}
		for( int j = 1; j <= _d; ++j ) {
			scanf( "%d", &dd );
			g[i+f+n][f+2*n+dd] = 1;
		}
	}
	int ans = 0;
	memset( flow, 0, sizeof( flow ) );
	while( 1 ) {
		memset( a, 0, sizeof ( a ) );
		a[0] = inf;
		head = tail = 0;
		q[tail++] = 0;
		while( head < tail ) {
			int u = q[head++];
			for( int v = 0; v <= tot; ++v ) {
				if( !a[v] && g[u][v] > flow[u][v] ) {
					p[v] = u;
					q[tail++] = v;
					a[v] = min( a[u], g[u][v] - flow[u][v] );
				}
			}
		}
		if( a[tot] == 0 )
			break;
		for( int c = tot; c ; c = p[c] ) {
			flow[p[c]][c] += a[tot];
			flow[c][p[c]] -= a[tot];
		}
		ans += a[tot];
	}
	printf( "%d\n", ans );
	return 0;
}

你可能感兴趣的:(POJ3281 网络流 dining)