算法
(二分图多重匹配) $O(n^2*m^2logm)$
每个谷仓匹配v[i]次,记一个cnt即可,时间复杂度有点玄学(大概比上面这个小一点)
时间复杂度
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,m,a[N][25],v[25],cnt[25],used[25],mid,girl[25][N],st,ed;
bool Match(int x)
{
for(int i=st;i<=ed;i++)
{
int y=a[x][i];
if(used[y])continue;
used[y]=1;
if(cnt[y]<v[y]){girl[y][++cnt[y]]=x;return true;}
else
for(int j=1;j<=cnt[y];j++)
if(Match(girl[y][j])){girl[y][j]=x;return true;}
}
return false;
}
bool Calc()
{
memset(girl,0,sizeof(girl));
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof(used));
if(!Match(i))return false;
}
return true;
}
bool Check()
{
for(st=1;st<=m;st++)
{
ed=st+mid-1;
if(ed>m)break;
if(Calc())return true;
}
return false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)scanf("%d",&a[i][j]);
for(int i=1;i<=m;i++)scanf("%d",&v[i]);
int l=0,r=m;
while(l<=r)
{
mid=(l+r>>1);
if(Check())r=mid-1;
else l=mid+1;
}
printf("%d\n",l);
}