码迷,mamicode.com
首页 > 其他好文 > 详细

网络流

时间:2015-11-19 22:17:30      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

    网络流是一种神奇的东西,它的问题大致为:你在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\n",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,且代价最小。
    同样是增广路算法,最后一个循环做完后有标记的点和未标记的点分为两个点集,删去连接两个点集的点,即为最小割。
    费用流
    在最大流的基础上,每条道路都有一定费用,要求在物资最多的前提下费用最小。
    只须在增广路中加一点判断使费用最小就行了。

  完……

网络流

标签:

原文地址:http://www.cnblogs.com/Enceladus/p/4979135.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!