/***************************************************************************/ |典型的二分图匹配:1274 Accepted 296K 16MS C++ 1073B 2011-06-10 18:41:18 |一定要熟记找增光路的思想,因为总感觉这个算法太给力了 /***************************************************************************/ #include<iostream> using namespace std; const int maxn = 201; int g[maxn][maxn]; int link[maxn]; int vis[maxn]; int n, m; /*dfs 找增广路径*/ bool dfs(int u) { for(int v=1; v<=m; v++) { if(g[u][v] && !vis[v]) { vis[v] = 1; if( !link[v] || dfs(link[v]) )/*dfs(link[v]是算法的核心部分,用来找增光路*/ { link[v] = u; return true; } } } return false; } /*最大匹配算法*/ int maxMatch() { int ret = 0; memset(link, 0, sizeof(link)); for(int i=1; i<=n; i++) { memset(vis, 0, sizeof(vis));/*X 集合的一个顶点找到匹配边后, 在下一个顶点找时要从新设置vis[i]为false*/ if(dfs(i)) ret += 1; } return ret; } int main() { int edge_num, to; while(scanf("%d%d", &n, &m)!=EOF) { memset(g,0, sizeof(g)); for(int i=1; i<=n; i++) { scanf("%d", &edge_num); for(int j=0; j<edge_num; j++) { scanf("%d", &to); g[i][to] = 1; } } int ret = maxMatch(); printf("%d/n", ret); } return 0; }