二分图,匈牙利算法:
1 //1274,2239,2584,2536,2446 2 //http://wenku.baidu.com/view/9962910590c69ec3d5bb75da.html 贪心最大二分匹配 3 //匈牙利树和增广轨 4 5 #include <cstdio> 6 #include <cstring> 7 8 int used[610]; //是否在覆盖点中 9 10 int nmap[610][610]; 11 12 int path[610];//前一个 13 14 int P,N; 15 16 int cross(int k) 17 { 18 19 int i; 20 for(i=1;i<=N;i++) 21 { 22 if(!nmap[k][i] || used[i]) continue; 23 24 used[i] = 1; 25 if(path[i] == -1 || cross(path[i])) 26 { 27 path[i] = k; 28 return 1; 29 } 30 } 31 return 0; 32 } 33 34 int hungray() 35 { 36 int i; 37 int nret = 0; 38 memset(path,-1,sizeof(path)); 39 for(i=1;i<=P;i++) 40 { 41 if(cross(i)) nret++; 42 memset(used,0,sizeof(used)); 43 } 44 return nret; 45 } 46 47 int main() 48 { 49 //freopen("in.txt","r",stdin); 50 //freopen("out.txt","w",stdout); 51 int tcase,i,j,a,b,c; 52 //scanf("%d",&tcase); 53 while(~scanf("%d%d",&P,&N)) 54 { 55 memset(nmap,0,sizeof(nmap)); 56 for(i=1;i<=P;i++) 57 { 58 scanf("%d",&c); 59 for(j=0;j<c;j++) 60 { 61 scanf("%d",&a); 62 nmap[i][a] = 1; 63 } 64 } 65 printf("%d\n",hungray()); 66 } 67 return 0; 68 }