题目大意
输入数据中,第一行给出n,表示n个奶牛。
接下来n行,每行一个x,xi表示第i头奶牛可以选择x个谷仓中的一个进行匹配。接下来x个数,表示谷仓的编号(1~n之间)
一个谷仓也只能有一头奶牛,问最多可以有多少组匹配。
这道题作为二分图匹配模版是再好不过了。
先讲一讲什么是二分图:一个图中,如果能够把所有的点分成两堆,使得任何一条边的两个顶点分属两堆,则是二分图。
具体长成这个样子:
那么如果我们选一定数量的边,使得这些边两两之间没有公共顶点,求最大的边数。
这种题我们使用匈牙利算法求解,可以看我的博客:匈牙利算法-二分图匹配(还没写)
所以这道题的代码就呼之欲出了:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 int n,m; 5 int first[205]; 6 int len=0; 7 bool map[205][205]; 8 int match[205]; 9 bool chw[205]; 10 bool find_mn(int x) 11 { 12 for(int i=1;i<=m;i++) 13 { 14 if(map[x][i]==true && chw[i]==true) 15 { 16 chw[i]=false; 17 if(match[i]==0 || find_mn(match[i])==true) 18 { 19 match[i]=x; 20 return true; 21 } 22 } 23 } 24 return false; 25 } 26 int main() 27 { 28 while(scanf("%d %d",&n,&m)!=EOF) 29 { 30 memset(first,0,sizeof(first)); 31 memset(map,false,sizeof(map)); 32 len=0; 33 for(int i=1;i<=n;i++) 34 { 35 int x; 36 scanf("%d",&x); 37 for(int j=1;j<=x;j++) 38 { 39 int soy; 40 scanf("%d",&soy); 41 map[i][soy]=true; 42 } 43 } 44 int ans=0; 45 memset(match,0,sizeof(match)); 46 for(int i=1;i<=n;i++) 47 { 48 memset(chw,true,sizeof(chw)); 49 if(find_mn(i)==true)ans++; 50 } 51 printf("%d\n",ans); 52 } 53 return 0; 54 }