題意:
要給通訊錄分組..每個人只能分到其特定的分組之一..問能使最大的分組最小為多少..
題解:
開始題目看錯了..看成要使最大的分組很最小的分組差值最小..然後跪了...
按題目這個意思還是很簡單的...二分枚舉容量..然後做二分圖的多重匹配判斷...
Program:
#include<iostream>#include<stdio.h>#include<algorithm>#include<cmath>#include<stack>#include<string.h>#include<queue>#define ll long long#define esp 1e-5#define MAXN 1006#define MAXM 5000000#define oo 100000007using namespace std;int n,m,num[MAXN],line[MAXN][MAXN];bool g[MAXN][MAXN],used[MAXN];bool dfs(int x,int C){ for (int i=1;i<=m;i++) if (g[x][i] && !used[i]) { used[i]=true; if (num[i]<C) { line[i][++num[i]]=x; return true; } for (int j=1;j<=num[i];j++) if (dfs(line[i][j],C)) { line[i][j]=x; return true; } } return false;}bool getmax(int C){ memset(num,0,sizeof(num)); for (int i=1;i<=n;i++) { memset(used,false,sizeof(used)); if (!dfs(i,C)) return false; } return true;}int main() { int i,x; char c; while (~scanf("%d%d",&n,&m) && n) { memset(g,false,sizeof(g)); for (i=1;i<=n;i++) { do { c=getchar(); }while (c<'0' || c>'9'); while (1) { x=0; while (c>='0' && c<='9') { x=x*10+c-'0'; c=getchar(); } g[i][x+1]=true; if (c=='\n') break; do { c=getchar(); }while (c==' '); if (c=='\n') break; } } int l=0,r=1005,mid; while (r-l>1) { mid=r+l>>1; if (!getmax(mid)) l=mid; else r=mid; } printf("%d\n",r); } return 0; }