码迷,mamicode.com
首页 > 编程语言 > 详细

最大流——dinic算法

时间:2019-01-09 11:21:55      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:介绍   style   code   路径   clu   拓扑序   通过   +=   can   

  上回介绍了EP算法,这次来学一个效率更高的算法。我们在做EP算法的时候,每次bfs最多遍历了整个残量网络,但是只找到了一条增广路。所以有可以优化的地方。Dinic算法基于分层图,我们先bfs找到一个合法的有向无环图(图中所有边都有残流,图严格按照拓扑序),然后在这张分层图上通过深度优先搜索找到若干条合法不冲突的增广路,累加到maxflow里。并且可以在dfs里添加剪枝:如果当前点以后找不到残流路径,把它直接从分层图中删掉。

  Dinic算法的时间复杂度为O(n^2*m)。实际运用远远小于这个上界,可以说是比较容易实现的效率最高的网络流算法之一,一般可以处理10^4~10^5的网络。特别的,Dinic算法求解二分图最大匹配的时间复杂度为O(m*sqrt(n))。

//Dinic求二分图最大匹配 
#include<bits/stdc++.h>
using namespace std;
const int inf=1<<29,N=20100,M=2e6+20;
int n,m,e,tot=1,s,t,maxflow,flow,d[N],Next[M],ver[M],lin[N],edge[M];
void add(int x,int y,int c){
    ver[++tot]=y;Next[tot]=lin[x];edge[tot]=c;lin[x]=tot;
    ver[++tot]=x;Next[tot]=lin[y];edge[tot]=0;lin[y]=tot;
}
bool bfs(){
    memset(d,0,sizeof(d));
    queue<int>q;
    q.push(s);d[s]=1;
    while(q.size()){
        int x=q.front();q.pop();
        for(int i=lin[x];i;i=Next[i]){
            int y=ver[i];
            if(edge[i]&&!d[y]){
                d[y]=d[x]+1;
                q.push(y);
                if(y==t) return 1;
            }
        }
    }
    return 0;
}
int dinic(int x,int flow){
    if(x==t) return flow;
    int rest=flow;
    for(int i=lin[x];i&&rest;i=Next[i]){
        int y=ver[i];
        if(d[y]==d[x]+1&&edge[i]){
            int k=dinic(y,min(rest,edge[i]));
            if(!k) d[y]=0;
            rest-=k;
            edge[i]-=k;
            edge[i^1]+=k;
        }
    }
    return flow-rest;
}
int main(){
    scanf("%d%d%d",&n,&m,&e);
    s=0,t=n+m+1;
    for(int i=1;i<=e;++i){
        int x,y;scanf("%d%d",&x,&y);
        if(y>m) continue;
        add(x,y+n,1);
    }
    for(int i=1;i<=n;++i) add(s,i,1);
    for(int i=1;i<=m;++i) add(i+n,t,1);
    while(bfs())
        while(flow=dinic(s,inf)) maxflow+=flow;
    printf("%d\n",maxflow);
    return 0; 
}

 

最大流——dinic算法

标签:介绍   style   code   路径   clu   拓扑序   通过   +=   can   

原文地址:https://www.cnblogs.com/kgxw0430/p/10242368.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!