最小费用最大流<模板大法好QAQ>

先贴一个神犇送我的模板QAQ

bool bfs() // 求最短路,并且查看是否存在可增广路 
{
    Rep_0(i,N)dis[i] = inf; //初始化费用 
    int h,t;
    dis[q[h = t = 1] = S] = 0,inq[S] = 1,flw[S] = inf;
    while(h <= t)
    {
        int x = q[h ++];
        RepG(i,x)
            if(fl && dis[v] > dis[x] + cst) // 有流 && 可松弛 
            {
                pre[v] = i ^ 1; //记录最短路的反向边路径 
                dis[v] = dis[x] + cst; //松弛 
                flw[v] = min(flw[x],fl); //flw[v]表示从S -> v的沿此条路径可获得的流量 
                if(!inq[v])inq[q[++ t] = v] = 1; 
            }
        inq[x] = 0;
    }
    return dis[T] != inf; //是否存在增广路 
}
int CostFlow()
{
    int s = 0;int i ;
    while(bfs())
    {
        for(int x = T;x != S;x = v)i = pre[x],fl += flw[T],vfl -= flw[T]; //走反向边,并且清掉路过的流量 
        s += flw[T] * dis[T];
        //因为下次增广会覆盖掉flw数组,所以flw数组不用清零 
    }
    return s;
}

已经注释。应该算是挺好懂的,比dinic不知道好懂到哪里去了。
接下来介绍几道题<从hzwer的blog上扒下来的>
bzoj1221:[HNOI]软件开发
Description
某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛巾,这种消毒毛巾使用一天后必须再做消毒处理后才能使用。消毒方式有两种,A种方式的消毒需要a天时间,B种方式的消毒需要b天(b>a),A种消毒方式的费用为每块毛巾fA, B种消毒方式的费用为每块毛巾fB,而买一块新毛巾的费用为f(新毛巾是已消毒的,当天可以使用);而且f>fA>fB。公司经理正在规划在这n天中,每天买多少块新毛巾、每天送多少块毛巾进行A种消毒和每天送多少块毛巾进行B种消毒。当然,公司经理希望费用最低。你的任务就是:为该软件公司计划每天买多少块毛巾、每天多少块毛巾进行A种消毒和多少毛巾进行B种消毒,使公司在这项n天的软件开发中,提供毛巾服务的总费用最低。
题解:
要注意到每天可以洗很多毛巾,但是每天产生的脏毛巾的数目是一定的,我们对于每天的脏毛巾和每天的需求进行考虑。
首先,每天都会产生nd[i]的脏毛巾,并且每天要么凭空多出新毛巾,要么拿以前的脏毛巾消毒后进行供应。
凭空:从S到某个点连上流量为 ndi ,费用为 f <script type="math/tex" id="MathJax-Element-184">f</script>的边。
拿以前的脏毛巾:从脏毛巾到当前时间 +消毒时间的地方连一个费用为消毒的话费,流量为当天的需求的边。
总建图的话:
首先是个二分图,左边为脏毛巾,右边为需要的干净毛巾。

    Rep(i,n)
    {
        save(S,i + n,nd[i],f);
        save(S,i,nd[i]);
        if(i != n)save(i,i + 1,inf);
        save(i + n,T,nd[i]);
        if(i + a < n)save(i,i + a + 1 + n,nd[i + a + 1],fa);
        if(i + b < n)save(i,i + b + 1 + n,nd[i + b + 1],fb);
    }

这道题关键在于需要把脏毛巾和需求的毛巾分开考虑。
其它题先放着……看了半天图论恶心死了
~~不太喜欢网络流系列~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值