题目来源:http://poj.org/problem?id=3189
题意
题意杀。。。
额,给出了n头牛,还有b个牛圈,然后每头牛对b个牛圈内心深处有自己的评价,也就是相对来说更喜欢去哪个牛圈,有自己的排名。。。然后嘞,牛圈在牛心中的排名差计算方法为:所有牛中最大排名和最小排名之差。问最小的排名差。。。
思路
简单的一个多重匹配问题,就是题意不好理解,,多重匹配里有两种解法,一种使用二分范围,一种是类似滑动窗的枚举。。
代码
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000+10;
int ranks[maxn][maxn];
int group[maxn][maxn],vis[maxn],top[maxn];
int n,m,left,right;
void init()
{
for(int i=1; i<=n; i++)
{
int x;
for(int j=1; j<=m; j++)
{
scanf("%d",&x);
ranks[i][x]=j;
}
}
for(int i=1; i<=m; i++)
scanf("%d",&top[i]);
}
bool dfs(int i)
{
for(int j=1; j<=m; j++)
{
if(!vis[j]&&ranks[i][j]>=left&&ranks[i][j]<=right)
{
vis[j]=1;
if(group[j][0]<top[j])
{
group[j][++group[j][0]]=i;
return true;
}
for(int k=1; k<=group[j][0]; k++)
{
if(dfs(group[j][k]))
{
group[j][k]=i;
return true;
}
}
}
}
return false;
}
bool judge()
{
memset(group,0,sizeof(group));
for(int i=1; i<=n; i++)
{
memset(vis,0,sizeof(vis));
if(!dfs(i))
return false;
}
return true;
}
void solve()
{
int ret=0x3f3f3f3f;
right=1,left=1;
while(left<=right&&right<=m)
{
if(judge())
{
int tmp=right-left+1;
if(tmp<ret)
ret=tmp;
left++;
}
else
right++;
}
printf("%d\n",ret);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
solve();
}
}