题意:
要给通讯录分组..每个人只能分到其特定的分组之一..问能使最大的分组最小为多少..
题解:
开始题目看错了..看成要使最大的分组很最小的分组差值最小..然后跪了...
按题目这个意思还是很简单的...二分枚举容量..然后做二分图的多重匹配判断...
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 100000007
using 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;
}