关于网络流sap算法

今天终于学习了网络流。。之前一直很怕这类问题,个人觉得网络流算是图论里面最难的了。。。。

sap学习下来感觉一般,关于解法都是意识流,细节也是蛮多的。。

我这里先贴一份模版,自已也加了点注释(只是个人的见解。。)

 

int isap(int x,int s)//s表示当前最多可以流多少
{
    if(x==n) return s;//到终点是直接返回答案
    int flow=0,Min=n-1,i;//min最大为n-1
    for(i=head[x];i!=-1;i=Next[i])
    {
        int y=to[i];
        if(v[i]>0)
        {
            if(dis[x]==dis[y]+1)//合法
            {
                int tmp=isap(y,min(s-flow,v[i]));
                //flow表示从这个点流出多少
                //tmp比表示向y可得的最大流
                flow+=tmp;//在当前向y的这个分支可以增加tmp的流量
                v[i]-=tmp;
                v[i^1]+=tmp;//反向标记,退流
            }
            Min=min(Min,dis[y]);//用于最后dis数组的更新
            //这句话要加在后面,因为dis数组还会更新
        }
        if(flow==s) return flow;
        //优化1--如果当前已经流满了,直接返回答案
        if(dis[1]==n) return flow;
        //优化2--如果整张图已经不存在增广路,直接退出
    }
    if(flow==0)//如果找不到路径,则需更改dis数组
    {
        gap[dis[x]]--;//gap由于计数
        if(gap[dis[x]]==0) dis[1]=n;//出现断层,整张图将不存在增广路
        dis[x]=Min+1;//dis数组为儿子编号最小值+1
        gap[dis[x]]++;
    }
    return flow;
}

  

isap函数是寻找一次增广路,具体要找到不存在增广路为止。

 

while(dis[1]<n)//如果存在增广路,则一直做下去
        ans+=isap(1,1e9);

 

  

 

posted @ 2016-07-16 19:23  lwq12138  阅读(696)  评论(0编辑  收藏  举报