题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2879

题意:有n道菜,每道菜需要b[i]份,m个厨师,第j个厨师做第i道菜需要时间a[i][j],求做完所有菜,所有人等待的最小总时间。

思路:设所有的菜为sum。一个明显的思路是将每个厨师拆成sum个点。然后sum个菜每个菜向每个厨师的每个点连边,表示该道菜为该厨师第几个做。由于这样数据太大。动态加边。每次增光一次后找到此次增广的厨师,每道菜将其连边。

struct node
{
    int u,v,next,cost,cap;
};

node edges[N*5];
int head[N],e;

void add(int u,int v,int cap,int cost)
{
    e++;
    edges[e].u=u;
    edges[e].v=v;
    edges[e].cap=cap;
    edges[e].cost=cost;
    edges[e].next=head[u];
    head[u]=e;
}

void Add(int u,int v,int cap,int cost)
{
    add(u,v,cap,cost);
    add(v,u,0,-cost);
}

int pre[N],F[N],C[N],visit[N];

int SPFA(int s,int t,int n)
{
    int i;
    for(i=0;i<=n;i++) F[i]=0,C[i]=INF,visit[i]=0;
    queue<int> Q;
    Q.push(s); F[s]=INF; C[s]=0;
    int u,v,cost,cap;
    while(!Q.empty())
    {
        u=Q.front();
        Q.pop();

        visit[u]=0;
        for(i=head[u];i;i=edges[i].next)
        {
            if(edges[i].cap>0)
            {
                v=edges[i].v;
                cost=edges[i].cost;
                cap=edges[i].cap;
                if(C[v]>C[u]+cost)
                {
                    C[v]=C[u]+cost;
                    F[v]=min(F[u],cap);
                    pre[v]=i;
                    if(!visit[v]) visit[v]=1,Q.push(v);
                }
            }
        }
    }
    return F[t];
}

int s,t,n,m,a[55][105],b[105],cnt[105],last[105];

int main()
{
    RD(n,m);
    int sum=0,i,j,x;
    FOR1(i,n) RD(b[i]),sum+=b[i];
    e=1;
    s=0; t=n+m+sum+1;
    FOR1(i,n)
    {
        Add(s,i,b[i],0);
        FOR1(j,m)
        {
            RD(a[i][j]);
            Add(i,n+j,1,a[i][j]);
        }
    }
    FOR1(i,m)
    {
        cnt[i]=1;
        Add(n+i,t,1,0);
        last[i]=e;
    }
    int ans=0,temp;
    while(sum--)
    {
        temp=SPFA(s,t,t);
        for(i=t;i!=s;i=edges[pre[i]].u)
        {
            x=pre[i];
            ans+=temp*edges[x].cost;
            edges[x].cap-=temp;
            edges[x^1].cap+=temp;
        }
        for(j=1;j<=m&&edges[last[j]-1].cap;j++);
        cnt[j]++;
        FOR1(i,n) Add(i,n+m+sum,1,a[i][j]*cnt[j]);
        Add(n+m+sum,t,1,0);
        last[j]=e;
    }
    PR(ans);
}

BZOJ 2879 美食节(费用流-动态加边)的更多相关文章

  1. BZOJ 2879: [Noi2012]美食节( 费用流 + 动态加边 )

    倒着做菜..然后考虑为当前的人做菜对后面的人的影响就可以了..要动态加边 --------------------------------------------------------------- ...

  2. 【bzoj2879】[Noi2012]美食节 费用流+动态加边

    原文地址:http://www.cnblogs.com/GXZlegend 题目描述 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他 ...

  3. [BZOJ2879] [Noi2012] 美食节 (费用流 & 动态加边)

    Description CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽 ...

  4. [NOI2012][bzoj2879] 美食节 [费用流+动态加边]

    题面 传送门 思路 先看看这道题 修车 仔细理解一下,这两道题是不是一样的? 这道题的不同之处 但是有一个区别:本题中每一种车有多个需求,但是这个好办,连边的时候容量涨成$p\lbrack i\rbr ...

  5. [BZOJ1070] [SCOI2007] 修车 (费用流 & 动态加边)

    Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使 ...

  6. BZOJ 2879 [Noi2012]美食节 | 费用流 动态开点

    这道题就是"修车"的数据加强版--但是数据范围扩大了好多,应对方法是"动态开点". 首先先把"所有厨师做的倒数第一道菜"和所有菜连边,然后跑 ...

  7. [NOI2012]美食节——费用流(带权二分图匹配)+动态加边

    题目描述 小M发现,美食节共有n种不同的菜品.每次点餐,每个同学可以选择其中的一个菜品.总共有m个厨师来制作这些菜品.当所有的同学点餐结束后,菜品的制作任务就会分配给每个厨师.然后每个厨师就会同时开始 ...

  8. 【BZOJ 2879】[Noi2012]美食节 费用流

    思路同修车,就是多了一个骚气的操作:动态加边,我们通过spfa流的过程可以知道,我们一次只会跑一流量,最后一层边跑过就不会再悔改,所以说我们只会用到一大片里面的很少的点,所以我们如果可以动态加边的话我 ...

  9. [NOI2012]美食节(费用流)

    题目描述 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽管所有的菜品都 ...

随机推荐

  1. PAT乙级 1021. 个位数统计 (15)

    1021. 个位数统计 (15) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 给定一个k位整数N = dk-1 ...

  2. java 文件及流读取

    在Java语言的IO编程中,读取文件是分两个步骤:1.将文件中的数据转换为流,2.读取流内部的数据.其中第一个步骤由系统完成,只需要创建对应的流对象即可,对象创建完成以后步骤1就完成了,第二个步骤使用 ...

  3. SSIS 关于并发的两个设置

    1.MaxConcurrentExecutables(包级别的并发度控制) MaxConcurrentExecutables, a package level property in SSIS det ...

  4. 在IIS站点中Adomd.net集成认证账号问题

    最近在做一个Asp.net项目的时候 ,在C#代码里面用到了Adomd.net去连接SSAS服务器做MDX查询,开发完成后将Asp.net代码部署到IIS后发现Adomd.net老是连接不到SSAS服 ...

  5. 关于ScrollView中嵌套listview焦点滑动问题 解决

    (第三种,第四种简单推荐使用) 在这里我要提出的是,listview能滚动的前提是:当listview本身的高度小于listview里的子view. 第一种方法 只需在MainActivity中 找到 ...

  6. tcp socket

    1.TCP连接手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在"无差别&quo ...

  7. kdump failed

    kdump  是一种先进的基于 kexec 的内核崩溃转储机制.当系统崩溃时,kdump 使用 kexec 启动到第二个内核. 第二个内核通常叫做捕获内核,以很小内存启动以捕获转储镜像.第一个内核保留 ...

  8. JS和CSS的多浏览器兼容(2)

    2.Css的浏览器兼容性 方法一,根据不同的浏览器加载不同的css file <!DOCTYPE html>  <html> <head> <title> ...

  9. java数组初始化

    java数组初始化 //静态初始化数组:方法一 String cats[] = new String[] { "Tom","Sam","Mimi&qu ...

  10. js中字符串转换为数字的方法

    parseInt; parseFload; +; parseInt() 和 parseFloat() 函数会尝试逐个解析字符串中的字符,直到遇上一个无法被解析成数字的字符,然后返回该字符前所有数字字符 ...