Steady Cow Assignment
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 6914   Accepted: 2387

Description

Farmer John's N (1 <= N <= 1000) cows each reside in one of B (1 <= B <= 20) barns which, of course, have limited capacity. Some cows really like their current barn, and some are not so happy.

FJ would like to rearrange the cows such that the cows are as equally happy as possible, even if that means all the cows hate their assigned barn.

Each cow gives FJ the order in which she prefers the barns. A cow's happiness with a particular assignment is her ranking of her barn. Your job is to find an assignment of cows to barns such that no barn's capacity is exceeded and the size of the range (i.e., one more than the positive difference between the the highest-ranked barn chosen and that lowest-ranked barn chosen) of barn rankings the cows give their assigned barns is as small as possible.

Input

Line 1: Two space-separated integers, N and B

Lines 2..N+1: Each line contains B space-separated integers which are exactly 1..B sorted into some order. The first integer on line i+1 is the number of the cow i's top-choice barn, the second integer on that line is the number of the i'th cow's second-choice barn, and so on.

Line N+2: B space-separated integers, respectively the capacity of the first barn, then the capacity of the second, and so on. The sum of these numbers is guaranteed to be at least N.

Output

Line 1: One integer, the size of the minumum range of barn rankings the cows give their assigned barns, including the endpoints.

Sample Input

6 4
1 2 3 4
2 3 1 4
4 2 3 1
3 1 2 4
1 3 4 2
1 4 2 3
2 1 3 2

Sample Output

2

二分长度+枚举
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1500;
int head[N],tot,S,T;
int q[N],dis[N],n,m;
int mp[N][22],cap[22];
struct node
{
    int next,v,w;
} e[N*100];
void add(int u,int v,int w)
{
    e[tot].v=v;
    e[tot].w=w;
    e[tot].next=head[u];
    head[u]=tot++;
}
bool bfs()
{
    memset(dis,-1,sizeof(dis));
    dis[S]=0;
    int l=0,r=0;
    q[r++]=S;
    while(l<r)
    {
        int u=q[l++];
        for(int i=head[u]; ~i; i=e[i].next)
        {
            int v=e[i].v;
            if(dis[v]==-1&&e[i].w>0)
            {
                q[r++]=v;
                dis[v]=dis[u]+1;
                if(v==T) return true;
            }
        }
    }
    return false;
}
int dfs(int s,int low)
{
    if(s==T||!low) return low;
    int ans=low,a;
    for(int i=head[s]; ~i; i=e[i].next)
    {
        if(e[i].w>0&&dis[e[i].v]==dis[s]+1&&(a=dfs(e[i].v,min(e[i].w,ans))))
        {
            e[i].w-=a;
            e[i^1].w+=a;
            ans-=a;
            if(!ans) return low;
        }
    }
    if(low==ans) dis[s]=-1;
    return low-ans;
}
bool solve(int l,int r)
{
    memset(head,-1,sizeof(head));
    tot=0;
    int ans=0;
    for(int i=1; i<=n; ++i) add(S,i,1),add(i,S,0);
    for(int i=1; i<=n; ++i) for(int j=l; j<=r; ++j) add(i,mp[i][j]+n,1),add(mp[i][j]+n,i,0);
    for(int i=1; i<=m; ++i) add(i+n,T,cap[i]),add(T,i+n,0);
    while(bfs()) ans+=dfs(S,1008611);
    if(ans==n) return true;
    return false;
}
int main()
{
    scanf("%d%d",&n,&m);S=0,T=n+m+1;
    for(int i=1; i<=n; ++i) for(int j=1; j<=m; ++j) scanf("%d",&mp[i][j]);
    for(int i=1; i<=m; ++i) scanf("%d",&cap[i]);
    int l=1,r=m,ans=m;
    while(l<=r) {
        int mid=(l+r)>>1;
        bool ok=0;
        for(int i=1;i+mid-1<=m;++i) if(solve(i,i+mid-1)) {
            ok=1;
            r=mid-1;
            ans=mid;
        }
        if(!ok) l=mid+1;
    }
    printf("%d\n",ans);
}

最新文章

  1. Centos7 配置网络步奏详解
  2. SQL Server 遇到 Automation服务器不能创建对象
  3. 读取Excel文件的两种方法
  4. 转载 JQuery.data()方法学习
  5. [转载]js javascript 判断字符串是否包含某字符串,String对象中查找子字符,indexOf
  6. Entity Framework Code First级联删除
  7. socket编程原理
  8. php生成图片验证码
  9. Unity3d Awake、OnEnable、Start生命周期
  10. XgCalendar日历插件动态添加参数
  11. UVa 10098: Generating Fast
  12. HttpRuntime详解分析
  13. 前端跨域方案-跨域请求代理(node服务)
  14. 浅谈SQL优化入门:2、等值连接和EXPLAIN(MySQL)
  15. 第四节基础篇 - SELECT 语句详解
  16. java--字符编码,正则表达式
  17. 菜鸟初学redis(二)
  18. Prism框架研究(一)
  19. 论文笔记:Visual Semantic Navigation Using Scene Priors
  20. c#中枚举类型 显示中文

热门文章

  1. 【Linux常见命令】tree命令
  2. HyperLeger Fabric开发(三)——HyperLeger Fabric架构
  3. CF思维联系– CodeForces - 991C Candies(二分)
  4. Linux中的程序和进程,PID和PPID
  5. redis系列之4----redis高级应用(集群搭建、集群分区原理、集群操作)
  6. turtle库应用实例3-叠加等边三角形绘制(一笔画)
  7. vue项目兼容ie
  8. Spring 框架介绍 [Spring 优点][Spring 应用领域][体系结构][目录结构][基础 jar 包]
  9. hadoop中如何动态更新集群队列和容量
  10. 201771010113 李婷华《面向对象程序设计(Java)》第十二周总结