关于网络流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);
一念起,天涯咫尺; 一念灭,咫尺天涯。