Dinic:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<stack>
using namespace std;
#define inf 0x3f3f3f3f
#define eps 1e-7
#define LL long long
#define ULL unsigned long long
#define MP make_pair
#define pb push_back
#define ls ( i << 1 )
#define rs ( ls | 1 )
#define md ( ( ll[i] + rr[i] ) >> 1 )
#define mxn 1020
int q[mxn*mxn];
struct edge {
int u, v, cap, flow;
edge() {}
edge( int u, int v, int cap, int flow ): u( u ), v( v ), cap( cap ), flow( flow ) {}
};
struct Dinic {
int n, m, s, t;
vector<edge> edges;
vector<int> G[mxn];
bool vis[mxn];
int d[mxn], cur[mxn];
void add( int u, int v, int cap ) {
edges.push_back( edge( u, v, cap, 0 ) );
edges.push_back( edge( v, u, 0, 0 ) );
m = edges.size();
G[u].push_back( m - 2 );
G[v].push_back( m - 1 );
}
bool bfs() {
memset( vis, 0, sizeof( vis ) );
int head = 0, tail = 1;
q[0] = s;
d[s] = 0, vis[s] = 1;
while( head < tail ) {
int x = q[head++];
for( int i = 0; i < G[x].size(); ++i ) {
edge &e = edges[G[x][i]];
if( !vis[e.v] && e.cap > e.flow ) {
vis[e.v] = 1;
d[e.v] = d[x] + 1;
q[tail++] = e.v;
}
}
}
return vis[t];
}
int dfs( int x, int a ) {
if( x == t || a == 0 )
return a;
int flow = 0, f;
for( int &i = cur[x]; i < G[x].size(); ++i ) {
edge &e = edges[G[x][i]];
if( d[x] + 1 == d[e.v] && ( f = dfs( e.v, min( a, e.cap - e.flow ) ) ) > 0 ) {
e.flow += f;
edges[G[x][i]^1].flow -= f;
flow += f;
a -= f;
if( a == 0 )
break;
}
}
return flow;
}
int calc( int s, int t ) {
this -> s = s, this -> t = t;
int flow = 0;
while( bfs() ) {
memset( cur, 0, sizeof( cur ) );
flow += dfs( s, inf );
}
return flow;
}
}solver;
int n, f, d;
int main() {
while( scanf( "%d%d%d", &n, &f, &d ) != EOF ) {
for( int i = 1; i <= n; ++i ) {
int n1, n2;
scanf( "%d%d", &n1, &n2 );
for( int j = 1; j <= n1; ++j ) {
int u;
scanf( "%d", &u );
solver.add( u, f + i, 1 );
}
for( int j = 1; j <= n2; ++j ) {
int u;
scanf( "%d", &u );
solver.add( f + n + i, f + 2 * n + u, 1 );
}
}
for( int i = 1; i <= n; ++i )
solver.add( f + i, f + n + i, 1 );
int tot = f + 2 * n + d + 1;
for( int i = 1; i <= f; ++i )
solver.add( 0, i, 1 );
for( int i = 1; i <= d; ++i )
solver.add( f + 2 * n + i, tot, 1 );
printf( "%d\n", solver.calc( 0, tot ) );
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<stack>
using namespace std;
#define inf 0x3f3f3f3f
#define eps 1e-7
#define LL long long
#define ULL unsigned long long
#define MP make_pair
#define pb push_back
#define ls ( i << 1 )
#define rs ( ls | 1 )
#define md ( ( ll[i] + rr[i] ) >> 1 )
#define mxn 1020
int q[mxn*mxn];
struct edge {
int u, v, cap, flow;
edge() {}
edge( int u, int v, int cap, int flow ): u( u ), v( v ), cap( cap ), flow( flow ) {}
};
struct isap {
int n, m, s, t;
vector<edge> edges;
vector<int> G[mxn];
bool vis[mxn];
int d[mxn], cur[mxn];
int p[mxn], num[mxn];
void add( int u, int v, int cap ) {
edges.push_back( edge( u, v, cap, 0 ) );
edges.push_back( edge( v, u, 0, 0 ) );
m = edges.size();
G[u].push_back( m - 2 );
G[v].push_back( m - 1 );
}
int Aug() {
int x = t, a = inf;
while( x != s ) {
edge &e = edges[p[x]];
a = min( a, e.cap - e.flow );
x = edges[p[x]].u;
}
x = t;
while( x != s ) {
edges[p[x]].flow += a;
edges[p[x]^1].flow -= a;
x = edges[p[x]].u;
}
return a;
}
bool bfs() {
memset( vis, 0, sizeof( vis ) );
int head = 0, tail = 1;
q[0] = t;
d[t] = 0, vis[t] = 1;
while( head < tail ) {
int x = q[head++];
for( int i = 0; i < G[x].size(); ++i ) {
edge &e = edges[G[x][i]];
if( !vis[e.v] && e.cap == 0 ) {
vis[e.v] = 1;
d[e.v] = d[x] + 1;
q[tail++] = e.v;
}
}
}
return vis[s];
}
int mf( int s, int t ) {
this -> s = s, this -> t = t;
int flow = 0;
bfs();
memset( num, 0, sizeof( num ) );
for( int i = 0; i < n; ++i )
num[d[i]] ++;
int x = s;
memset( cur, 0, sizeof( cur ) );
while( d[s] < n ) {
if( x == t )
flow += Aug(), x = s;
int ok = 0;
for( int i = cur[x]; i < G[x].size(); ++i ) {
edge &e = edges[G[x][i]];
if( e.cap > e.flow && d[x] == d[e.v] + 1 ) {
ok = 1;
p[e.v] = G[x][i];
cur[x] = i;
x = e.v;
break;
}
}
if( !ok ) {
int m = n - 1;
for( int i = 0; i < G[x].size(); ++i ) {
edge &e = edges[G[x][i]];
if( e.cap > e.flow )
m = min( m, d[e.v] );
}
if( --num[d[x]] == 0 )
break;
num[d[x] = m + 1]++;
cur[x] = 0;
if( x != s )
x = edges[p[x]].u;
}
}
return flow;
}
}solver;
int n, f, d;
int main() {
while( scanf( "%d%d%d", &n, &f, &d ) != EOF ) {
for( int i = 1; i <= n; ++i ) {
int n1, n2;
scanf( "%d%d", &n1, &n2 );
for( int j = 1; j <= n1; ++j ) {
int u;
scanf( "%d", &u );
solver.add( u, f + i, 1 );
}
for( int j = 1; j <= n2; ++j ) {
int u;
scanf( "%d", &u );
solver.add( f + n + i, f + 2 * n + u, 1 );
}
}
for( int i = 1; i <= n; ++i )
solver.add( f + i, f + n + i, 1 );
int tot = f + 2 * n + d + 1;
for( int i = 1; i <= f; ++i )
solver.add( 0, i, 1 );
for( int i = 1; i <= d; ++i )
solver.add( f + 2 * n + i, tot, 1 );
solver.n = tot + 1;
printf( "%d\n", solver.mf( 0, tot ) );
}
return 0;
}