zoukankan      html  css  js  c++  java
  • 网络流

        网络流是一种神奇的东西,它的问题大致为:你在S号城市拥有很多物资,现在你要把它们运到城市T,除此之外还有很多其他城市,有些城市间有道路,有些没有,且每条道路都有所运物资的最大量。你可以先把一些物资从S直接运向T(必须S到T有道路且运的物资总量小于这条道路的最大量),再把另一些运往A,再从A运向T(须S到A,A到T有道路,且运送物资量都小于这两条道路的最大量)
        最大流
        顾名思义就是求从S到T最多运多少物资,这个问题理解了也不难。
        不断重复以下步骤:
        1.维护一个队列,用类似SPFA的方法求出从S到每一个城市运送的可能的物资数(不为0,也不一定最大),并记录其父节点;
        2.判断是否有物资运到T城市,如果没有就退出循环;
        3.如果有物资运到T城市,就把当前记录的运到T的物资累加入总计,并把本次记录的从S到T的路径上每一条道路的最大量减去当前记录的值(代表吧这些物资运过去了)。
        这个方法叫增广路。
        代码如下(云神教的):

    int sap(int p,int f){
        if (p==ty) return f;
        int h=0;
        for (int i=d[p];i;i=bi[i].ne)
        if ((bi[i].l)&&(c[bi[i].y]+1==c[p])){
            int q=sap(bi[i].y,min(f-h,bi[i].l));
            //printf("%d %d
    ",bi[i].y,q);
            h+=q;
            bi[i].l-=q;bi[bi[i].pa].l+=q;d[p]=i;//当前弧优化
            if (h==f) return f;
        }
        if (c[sy]>=no) return h;//分层
        g[c[p]]--;
        if (!(g[c[p]])) c[sy]=no;
        c[p]++;
        g[c[p]]++;d[p]=la[p];
        return h;
    }

        最小割
        这是指摧毁掉一些道路,使得不可能有物资运从S到T,且代价最小。
        同样是增广路算法,最后一个循环做完后有标记的点和未标记的点分为两个点集,删去连接两个点集的点,即为最小割。
        费用流
        在最大流的基础上,每条道路都有一定费用,要求在物资最多的前提下费用最小。
        只须在增广路中加一点判断使费用最小就行了。

      完……

  • 相关阅读:
    如何编写测试用例
    bug的合规描述
    Linux常用命令学习
    测试用列设计
    软件质量管理
    测试的分类
    软件工程模型
    软件测试核心概念
    Thinking in C++ 第十三章 动态对象创建
    python urllib
  • 原文地址:https://www.cnblogs.com/Enceladus/p/4979135.html
Copyright © 2011-2022 走看看