二分图匹配,hopcroft-karp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 5010;
const int MAXM = 50010;
struct Edge{
int to, next;
}edge[ MAXM ];
int head[ MAXN ], tot;
void init(){
tot = 0;
memset( head, -1, sizeof( head ) );
}
void addedge( int u, int v ){
edge[ tot ].to = v;
edge[ tot ].next = head[ u ];
head[ u ] = tot++;
}
int linker[ MAXN ];
bool used[ MAXN ];
int uN;
bool dfs( int u ){
for( int i = head[ u ]; i != -1; i = edge[ i ].next ){
int v = edge[ i ].to;
if( !used[ v ] ){
used[ v ] = true;
if( linker[ v ] == -1 || dfs( linker[ v ] ) ){
linker[ v ] = u;
return true;
}
}
}
return false;
}
int hungary(){
int res = 0;
memset( linker, -1, sizeof( linker ) );
for( int u = 0; u < uN; ++u ){
memset( used, false, sizeof( used ) );
if( dfs( u ) )
res++;
}
return res;
}
int main(){
int n;
while( scanf( "%d", &n ) != EOF ){
init();
int sum = 0;
for( int i = 0;i < n; ++i ) {
int temp1, temp2, temp;
scanf( "%d: (%d)", &temp1, &temp2 );
sum += temp2;
// cout << temp1 << " " << temp2 << endl;
while( temp2-- ){
scanf( "%d", &temp );
addedge( temp1, temp );
}
}
uN = n;
int ans = hungary();
cout << n - ans / 2 << endl;
}
return 0;
}