图论算法-网络最大流【EK;Dinic】

图论算法-网络最大流模板【EK;Dinic】


EK模板

每次找出增广后残量网络中的最小残量增加流量

const int inf=1e9;
int n,m,s,t;
struct node{int v,cap;};
vector<node> map[100010];
int flow[10010][10010];
int a[100010];
int pre[100010];

int EK()
{
    int maxf;//记录最大流量
    queue<int> q;
    while(1)
    {
        memset(a,0,sizeof(a));
        a[s]=inf;
        q.push(s);
        
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int j=0;j<map[u].size();j++)
            {
                int v=map[u][j].v;
                int cap=map[u][j].cap;
                if(!a[v]&&cap>flow[u][v])
                {
                    pre[v]=u;
                    q.push(v);
                    a[v]=min(a[u],cap-flow[u][v]);
                }
            }
        }
        
        if(a[t]==0)
        break;
        
        for(int u=t;u!=s;u=pre[u])
        {
            flow[ pre[u] ][u]+=a[t];
            flow[ u][ pre[u] ]-=a[t];
        }
        maxf+=a[t];
    }
    return  maxf;
}

int main()
{
    cin>>n>>m>>s>>t;
    for(int i=1;i<=m;i++)
    {
        int u,v,dis;
        cin>>u>>v>>dis;
        map[u].push_back((node) {v,dis });
        map[v].push_back((node) {u,0 });//**高亮**反向边一定要记得建
    }
    
    int ans=EK();
    
    cout<<ans;
    return 0;
}

Dinic模板

构造层次+阻塞流增广

const int inf=1e9;
int n,m;
int s,t;
int tot=1;
struct node{int v,f,nxt;}E[1000010];
int head[100010];
int lev[100010];//记录层次

void add(int u,int v,int cap)
{
    E[++tot].v=v;
    E[tot].nxt=head[u];
    E[tot].f=cap;
    head[u]=tot;
}

bool bfs()
{
    queue<int> q;
    memset(lev,-1,sizeof(lev));
    q.push(s);
    lev[s]=0;
    
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=head[u];i;i=E[i].nxt)
        {
            int v=E[i].v;
            if(lev[v]==-1&&E[i].f)
            {
                lev[v]=lev[u]+1;
                if(v==t)
                return true;
                q.push(v);
            }
        }
    }
    return false;
}

int dfs(int u,int cap)
{
    if(u==t)
    return cap;
    
    int flow=cap;
    for(int i=head[u];i;i=E[i].nxt)
    {
        int v=E[i].v;
        if(lev[v]==lev[u]+1&&flow&&E[i].f>0)
        {
            int f=dfs(v,min(flow,E[i].f));
            flow-=f;
            E[i].f-=f;
            E[i^1].f+=f;
        }
    }
    return cap-flow;
}

int dinic()
{
    int maxf=0;
   
    while(bfs())//若s-t可达就不断构造层次图
    maxf+=dfs(s,inf);//s-t可达,用阻塞流增广

    return maxf;
}

int main()
{
    cin>>n>>m>>s>>t;
    for(int i=1;i<=m;i++)
    {
        int u,v,w;
        cin>>u>>v>>w;
        add(u,v,w);
        add(v,u,0);//**高亮**反向边一定要记得建
    }

    dinic();
    cout<<maxf;
    return 0;
}

相关推荐