zoukankan      html  css  js  c++  java
  • ZKW费用流的理解

    ORZ ZKW费用流这样的神牛算法,也只有对最短路理解很深度人才能想得出来了吧

    下面是我对这个算法的理解

    ZKW算法主要分为AUG和Modlabel两个过程

    其中Aug过程与普通的最大流DFS增广求法相似,但加入一个限制条件

    满足等式Dist[U]=Dist[V]+edge.cost才允许增广

    代码如下

    int aug(int u,int flow)
      {   if (u==T) {ans+=flow*dis[S]; return flow;}
          vis[u]=1; int now=0;
          for (int i=base[u];i;i=v[i].next)
          { int x=v[i].x; 
            if (vis[x]||!v[i].f||dis[u]!=dis[x]+v[i].cost)
              continue;
           int tmp=aug(x,min(flow-now,v[i].f));
           if (tmp) v[i].f-=tmp; v[v[i].op].f+=tmp;
           now+=tmp;  if (now==flow) return flow; 
         } return now;
      }
    Aug

    你可能感到奇怪,这个过程并不会进行,应为一开始Dist应该都为0,所以还需要Modlabel来修改距离

    int modlable()
      {  int del=inf;
         for (int i=S;i<=T;i++)
         if (vis[i]) 
         for (int j=base[i];j;j=v[j].next)
         if (v[j].f) {int x=v[j].x;  
          if (!vis[x]) del=min(del,dis[x]+v[j].cost-dis[i]);}
         if (del==inf) return 0;
         for (int i=S;i<=T;i++)
           if (vis[i]) vis[i]=0,dis[i]+=del,cur[i]=base[i]; return 1;
       }
    Modlabel

    当流网络不能再增广的时候,我们就修改距离,我们找出所有还有流量的边,并且边的起点被访问,但边终点未被访问

    显然这些边都是因为不满足Dist[U]=Dist[V]+edge.cost才被阻断的,我们记录所有满足边下中Dist[V]+edge.cost-Dist[U]最小值

    这样就能优先找出最短增广路,就能求出费用流了

    最后将两个过程和在一起

    int zkw()
      {  for (int i=S;i<=T;i++) cur[i]=base[i];
         do {while (aug(S,inf)) memset(vis,0,sizeof(vis));}
         while (modlable()); printf("%d
    ",ans);
       }
    ZKW
  • 相关阅读:
    Visual Studio 20**自动添加头部注释信息
    开发使用混合式Winform模块
    java 下拉框级联及相关(转)
    Redhat关闭SELinux和防火墙的办法(转)
    icmp的报文,Destination Host Unreachable
    负载均衡-lvs
    深入浅出交换类排序算法(转)
    单源最短路径(dijkstra算法)php实现
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    oracle递归函数
  • 原文地址:https://www.cnblogs.com/williamchenwl/p/3691917.html
Copyright © 2011-2022 走看看