[关闭]
@Junlier 2018-09-26T11:40:24.000000Z 字数 2915 阅读 4132

网络流题目详讲+题单(提高版)(持续更新中......)

图论——网络流
PS:如果你觉得自己还不够强(和我一样弱),可以去入门版看看

写在前面的话(潦草)

  • 这篇博客不会讲定义,理解啊什么的,那些知识点网络上......仅仅是题目详讲
    但是每一道题的题解和知识点还是会涵盖的
  • 笔者还很菜,还有很多不会,只是想让自己会了的题目大家更容易懂
  • 建议使用博客右边的主题切换,换成夜间模式可能看起来更舒服(随性)
  • 笔者根据自己的感受(也有一定参考性的)给题目编了个难度,有主观色彩,可以根据实际需要来选择

前置知识点:

网络流题目详讲(入门版)

题目来了:

PS:若无特殊说明,均为luogu上的题目,难度有标记

网络最大流/一般增广路(Dinic&EK)

难题开始

费用流

预流推进算法(一种新的很吊的求最大流的方法,据说非常优秀)

网络流题目需要注意的地方

PS:代码尚未过编译,现场手打的,有错误请指出
PS:有些凌乱,凑合着看

Part1 一定要记得

1. 建边时的"反边容量0"和"反边费用负"

  1. il void add(rg int p,rg int q,rg int o,rg int w)
  2. {//o为容量,w为费用(变量丑)
  3. ljl[++cnt]=(EDGE){q,hd[p],o, w},hd[p]=cnt;
  4. ljl[++cnt]=(EDGE){p,hd[q],0,-w},hd[q]=cnt;
  5. }

2. EK算法记录前驱并处理情况的跳点情况

  1. int flow=Inf;
  2. for(int i=T;i!=S;i=ljl[pre[i]^1].to)
  3. flow=min(flow,ljl[pre[i]].c);
  4. tot+=flow,ans+=flow*dis[T];
  5. for(int i=T;i!=S;i=ljl[pre[i]^1].to)
  6. ljl[pre[i]].c-=flow,ljl[pre[i]^1].c+=flow;

3. 当前弧优化记得每次都要重新赋值cur

  1. while(BFS())
  2. {
  3. for(int i=1;i<=n;++i)cur[i]=hd[i];//<--
  4. while(lst res=dfs(1,n,Inf))ans+=res;

4. 跑Dinic分层时dep[S]一定要赋值为1,不然死循环

  1. Q.push(S),dep[S]=1;//<--

5. 增广路时数组清零(还有数组的边界)

其实边界的话,我一般把S放在0号节点,T放在最后的节点,循环的时候就会顺手很多

  1. //Dinic的BFS
  2. for(int i=S;i<=T;++i)dep[i]=0;//<--
  3. //费用流的SPFA
  4. for(int i=S;i<=T;++i)dis[i]=Inf;//<--跑最大费用则为-Inf
  5. while(!Q.empty())Q.pop();
  6. dis[S]=0,Q.push(S),in[S]=1;

6. 费用流和最大流都可以跑环

Part2 技巧

看看xzy的,很详细啊

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注