无向图的最大独立集 = 顶点数 - 最小顶点覆盖
而对于二分图来说,最大匹配= 最小顶点覆盖
所以,下面就是用匈牙利算法求二分图的最大匹配了
//724K 391MS
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
int vnum;
const int maxvnum = 500+5;
vector<int> G[maxvnum];
int match[maxvnum];
bool used[maxvnum];
inline void add_edge(int u, int v){
G[u].push_back(v);
//G[v].push_back(u);
}
bool DFS(int v){
used[v] = true;
for(int i=0; i<G[v].size(); i++){
int u = G[v][i], w = match[u];
if(w < 0 || (!used[w] && DFS(w))){
match[v] = u;
match[u] = v;
return true;
}
}
return false;
}
int bi_match(){
int res = 0;
memset(match, -1, sizeof(match));
for(int v=0; v<vnum; v++){
if(match[v] < 0){
memset(used, 0, sizeof(used));
if(DFS(v)) res++;
}
}
return res;
}
int main(){
while(~scanf("%d", &vnum)){
for(int i=0; i<maxvnum+5; i++) G[i].clear();
for(int i=0; i<vnum; i++){
int a, num;
scanf("%d: (%d)", &a, &num);
for(int i=0; i<num; i++){
int b; scanf("%d", &b);
add_edge(a, b);
}
}
printf("%d\n", vnum - bi_match());
}
return 0;
}