zoukankan      html  css  js  c++  java
  • 学习笔记 --- 最小费用最大流

    最小费用最大流,本人一只三种算法,MCMF、zkw(张昆玮)、Primal-Daul。然而基本没见人用过PD,多数都是MCMF和zkw。
    对比起来,MCMF是基于spfa的一种算法,在稀疏图上十分高效;zkw算法是用spfa和KM重标号来进行计算的,在稠密图很高效,不过有一种图能够使zkw变慢:费用不小,容量不大,增广路比较长;

    zkw最小费用最大流:

    bool spfa()
    {
        memset(mark,0,sizeof(mark));
        for (int i=S; i<=T; i++) dis[i]=-1;
        h=0,t=1;
        q[0]=T;mark[T]=1;dis[T]=0;
        while (h<t)
            {
                int now=q[h];h++;mark[now]=0;
                for (int i=head[now]; i; i=edge[i].next)
                    if (edge[i^1].v && dis[now]+edge[i^1].c>dis[edge[i].to])
                        {   
                            dis[edge[i].to]=dis[now]+edge[i^1].c;
                            if (!mark[edge[i].to])
                                {
                                    mark[edge[i].to]=1;
                                    q[t++]=edge[i].to;
                                }
                        }
            }
        return dis[S]!=-1;
    }
    
    int dfs(int loc,int low)
    {
        mark[loc]=1;
        if (loc==T) return low;
        int w,used=0;
        for (int i=head[loc]; i; i=edge[i].next)
            if (dis[edge[i].to]==dis[loc]-edge[i].c && edge[i].v && !mark[edge[i].to])
                {
                    w=dfs(edge[i].to,min(low-used,edge[i].v));
                    ans+=w*edge[i].c;
                    edge[i].v-=w;edge[i^1].v+=w;
                    used+=w;if (used==low)  return low;
                }
        return used;
    }
    
    void zkw()
    {
        int tmp=0;
        while (spfa())
            {
                mark[T]=1;
                while (mark[T])
                    {
                        memset(mark,0,sizeof(mark));
                        tmp+=dfs(S,inf);
                    }
            }
    }
    ---2016.03.16
    

    浅谈线性规划类题目转费用流的建图方法:
    首先添加松弛变量,将不等号都变为等号。分别用下一个式子减去上一个式子,如果每个变量只出现了两次且符号一正一负,那么可以转化为费用流。对于每个式子建立一个点,那么每个变量对应一条边,从一个点流出,向另一个点流入。这样,对于等式右边的常数 C,如果是正的,对应从源点向该点连一条流量 C,费用 0 的边;如果是负的对应从该点向汇点连一条流量 −C,费用 0 的边。对于每个变量,从它系数为正的式子向系数为负的式子连一条容量为inf,费用为它在目标函数里系数的边。这样网络流模型就构造完毕了。
    详细例题可参考:http://blog.csdn.net/dad3zz/article/details/50815718

  • 相关阅读:
    其实 Linux IO 模型没那么难
    七年三次大重构,聊聊我的重构成长史
    听说 JVM 性能优化很难?今天我小试了一把!
    盘点三年来写过的原创文章
    如何快速实现一个连接池?
    树结构系列(四):MongoDb 使用的到底是 B 树,还是 B+ 树?
    树结构系列(三):B树、B+树
    树结构系列(二):平衡二叉树、AVL树、红黑树
    树结构系列(一):从普通树到二叉查找树
    静态代码分析工具清单
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5346223.html
Copyright © 2011-2022 走看看