题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1669
思路:由于要求minimize the size of the largest group,由此我们想到二分枚举,然后每一次求一下多重匹配就可以了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 1010 8 #define MAXM 555 9 vector<int>vet[MAXN]; 10 bool map[MAXN][MAXN]; 11 int Link[MAXM];//i当前的匹配数 12 int vLink[MAXM][MAXN];//与i匹配的第j个匹配的数k 13 bool mark[MAXM];//标记已匹配的 14 int n,m,limit,ans; 15 16 bool dfs(int u) 17 { 18 for(int i=0;i<vet[u].size();i++){ 19 int v=vet[u][i]; 20 if(!mark[v]){ 21 mark[v]=true; 22 if(Link[v]<limit){ 23 vLink[v][Link[v]]=u; 24 Link[v]++; 25 return true; 26 } 27 for(int j=0;j<Link[v];j++){ 28 if(dfs(vLink[v][j])){ 29 vLink[v][j]=u; 30 return true; 31 } 32 } 33 } 34 } 35 return false; 36 } 37 38 bool Match() 39 { 40 memset(Link,0,sizeof(Link)); 41 memset(vLink,0,sizeof(vLink)); 42 for(int i=0;i<n;i++){ 43 memset(mark,false,sizeof(mark)); 44 if(!dfs(i))return false; 45 } 46 return true; 47 } 48 49 int main() 50 { 51 // freopen("1.txt","r",stdin); 52 char name[22]; 53 int x; 54 while(scanf("%d%d",&n,&m),(n+m)){ 55 for(int i=0;i<n;i++)vet[i].clear(); 56 for(int i=0;i<n;i++){ 57 scanf("%s",name); 58 while(getchar()==' '){ 59 scanf("%d",&x); 60 vet[i].push_back(x); 61 } 62 } 63 int low=0,high=n; 64 while(low<=high){ 65 limit=(low+high)>>1; 66 if(Match()){ 67 ans=limit;//保留 68 high=limit-1; 69 }else 70 low=limit+1; 71 } 72 printf("%d ",ans); 73 } 74 return 0; 75 }