欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

【模板】EK求最大流、dinic求最大流

发布时间:2023/12/3 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 【模板】EK求最大流、dinic求最大流 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

ACM模板


目录

      • 概念
      • EK算法
      • Dinic算法

概念

yxc老师的部分总结

  • 基本概念
    1.1 流网络,不考虑反向边
    1.2 可行流,不考虑反向边
    1.2.1 两个条件:容量限制、流量守恒
    1.2.2 可行流的流量指从源点流出的流量 - 流入源点的流量
    1.2.3 最大流是指最大可行流
    1.3 残留网络,考虑反向边,残留网络的可行流f’ + 原图的可行流f = 原题的另一个可行流
    1.4 增广路径
    1.5 割
    1.5.1 割的定义
    1.5.2 割的容量,不考虑反向边,“最小割”是指容量最小的割。
    1.5.3 割的流量,考虑反向边,f(S, T) <= c(S, T)
    1.5.4 对于任意可行流f,任意割[S, T],|f| = f(S, T)
    1.5.5 对于任意可行流f,任意割[S, T],|f| <= c(S, T)
    1.5.6 最大流最小割定理
    (1) 流f是最大流
    (2) 流f的残留网络中不存在增广路
    (3) 存在某个割[S, T],|f| = c(S, T)
    1.6. 算法
    1.6.1 EK O(nm^2)
    1.6.2 Dinic O(n^2m)
    1.7 应用
    1.7.1 二分图
    (1) 二分图匹配
    (2) 二分图多重匹配
    1.7.2 上下界网络流
    (1) 无源汇上下界可行流
    (2) 有源汇上下界最大流
    (3) 有源汇上下界最小流
    1.7.3 多源汇最大流
  • EK算法

    链式前向星初始化-1版本 0正边 1反边
    S源点 T汇点
    d[]流量 pre[]前向边

    存图存的是残留网络
    时间复杂度:O(nm2)O(nm^2)O(nm2)

    constexpr int N=1010,M=20010; int h[N],e[M],ne[M],f[M],idx; int n,m; int S,T,flow[N],pre[N]; bool st[N]; void add(int a,int b,int c) {e[idx]=b,f[idx]=c,ne[idx]=h[a],h[a]=idx++;e[idx]=a,f[idx]=0,ne[idx]=h[b],h[b]=idx++; } bool bfs() {queue<int> q;memset(flow,0x3f,sizeof flow);memset(st,0,sizeof st);q.push(S);st[S]=1;while(q.size()){int u=q.front();q.pop();for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(f[i]&&!st[v]){st[v]=1;flow[v]=min(flow[u],f[i]);pre[v]=i;if(v==T) return 1;q.push(v);}}}return 0; } int EK() {int ans=0;while(bfs()){ans+=flow[T];for(int i=T;i!=S;i=e[pre[i]^1]){f[pre[i]]-=flow[T];f[pre[i]^1]+=flow[T];}}return ans; }

    Dinic算法

    模拟队列
    时间复杂度:O(n2m)O(n^2m)O(n2m)

    int h[N],e[M],ne[M],f[M],idx; int S,T,d[N],q[N],cur[N]; void add(int a,int b,int c) {e[idx]=b,ne[idx]=h[a],f[idx]=c,h[a]=idx++;e[idx]=a,ne[idx]=h[b],f[idx]=0,h[b]=idx++; } bool bfs() {memset(d,-1,sizeof d);int hh=0,tt=0;d[S]=0,cur[S]=h[S],q[0]=S;while(hh<=tt){int u=q[hh++];for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(d[v]==-1&&f[i]){d[v]=d[u]+1;cur[v]=h[v];// 当前弧优化if(v==T) return 1;q[++tt]=v;}}}return 0; } int dfs(int u=S,int flow=0x3f3f3f3f) {if(u==T) return flow;int rmn=flow;for(int &i=cur[u];i!=-1&&rmn;i=ne[i]){int v=e[i];if(d[v]==d[u]+1&&f[i]){int t=dfs(v,min(f[i],rmn));if(!t) d[v]=-1;// 优化f[i]-=t,f[i^1]+=t,rmn-=t;}}return flow-rmn; } int dinic() {int r=0;while(bfs()) r+=dfs();return r; }

    总结

    以上是生活随笔为你收集整理的【模板】EK求最大流、dinic求最大流的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。