[Template] EK for maximum flow, dinic for maximum flow

ACM template


concept

Partial summary of teacher yxc

1.1 Flow network, without considering the reverse side
1.2 Feasible flow, without considering the reverse side
1.2.1 Two conditions: capacity limitation, flow conservation
1.2.2 The flow of feasible flow refers to the flow from the source point-the flow into the source point
1.2.3 Maximum flow refers to the maximum feasible flow.
1.3 Residual network, considering the reverse side, the feasible flow of the residual network f'+ the feasible flow of the original graph f = another feasible flow of the original problem
(1) |f' + f| = |f'| + |f|
(2) |f'| may be a negative number
1.4 augmented path
1.5 cut
1.5.1 definition of
cut 1.5.2 capacity of cut, regardless of the reverse side, "minimum cut" means The cut with the smallest capacity.
1.5.3 The cut flow, considering the reverse side, f(S, T) <= c(S, T)
1.5.4 For any feasible flow f, any cut [S, T], |f| = f(S , T)
1.5.5 For any feasible flow f, any cut [S, T], |f| <= c(S, T)
1.5.6 Maximum flow minimum cut theorem
(1) Possible flow f is the maximum flow
(2 ) There is no augmentation path in the residual network of feasible flow f
(3) There is a certain cut [S, T], |f| = c(S, T)

EK algorithm

Before the initialization chain to the star version -1 0 1 trans positive-side edge
point source S T sink
d[]flow pre[]forward edge

memory is stored FIG residual network
time complexity: O (nm 2) O (2 ^ nm)O(nm2)

const int N=1010,M=20010;
int h[N],e[M],ne[M],f[M],idx;
int d[N],pre[N];
bool st[N];
int n,m,S,T;
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(st,0,sizeof st);
    queue<int> q;
    q.push(S);
    st[S]=1;
    d[S]=0x3f3f3f3f;
    while(q.size())
    {
    
    
        int t=q.front();q.pop();
        for(int i=h[t];i!=-1;i=ne[i])
        {
    
    
            int j=e[i];
            if(!st[j]&&f[i])
            {
    
    
                st[j]=1;
                d[j]=min(d[t],f[i]);
                pre[j]=i;  
                if(j==T) return 1;
                q.push(j);
            }
        }
    }
    return 0;
}
int EK()
{
    
    
    int r=0;
    while(bfs())
    {
    
    
        r+=d[T];
        for(int i=T;i!=S;i=e[pre[i]^1])
            f[pre[i]]-=d[T],f[pre[i]^1]+=d[T];
    }
    return r;
}

Dinic algorithm

Simulation queue
time complexity: O (n 2 m) O(n^2m)O ( n2 m)

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 tt=0,hh=0;
    q[S]=0,cur[S]=h[S],d[S]=0;
    while(hh<=tt)
    {
    
    
        int t=q[hh++];
        for(int i=h[t];i!=-1;i=ne[i])
        {
    
    
            int j=e[i];
            if(d[j]==-1&&f[i])
            {
    
    
                d[j]=d[t]+1;
                cur[j]=h[j];
                if(j==T) return 1;
                q[++tt]=j;
            }
        }
    }
    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 j=e[i];
        if(d[j]==d[u]+1&&f[i])
        {
    
    
            int t=dfs(j,min(f[i],rmn));
            if(!t) d[j]=-1;// 优化
            f[i]-=t,f[i^1]+=t,rmn-=t;
        }
    }
    return flow-rmn;
}
int dinic()
{
    
    
    int r=0;
    while(bfs()) r+=dfs();
    return r;
}

Guess you like

Origin blog.csdn.net/Fighting_Peter/article/details/113007587