最大流dinic算法模板(邻接矩阵)

说明:dinic算法论效率,比EK要好,比sap差一点,但是代码比sap简单许多,竞赛中一般使用dinic,除非要求效率非常高。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int VM=220;
const int INF=0x3f3f3f3f;
int n,m,src,des;
int map[VM][VM],dep[VM];    ///dep[i]表示当前点到起点src的层数

int BFS(){ /// 按照层次建图
    queue<int> q;
    memset(dep,-1,sizeof(dep));
    q.push(src);
    dep[src]=0;
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int v=1;v<=m;v++)
            if(map[u][v]>0 && dep[v]==-1) ///如果到达且没访问
                dep[v]=dep[u]+1,q.push(v);
    }
    return dep[des]!=-1;
}

int DFS(int u,int mi){ ///寻找增广路
    if(u==des) return mi;
    int tmp;
    for(int v=1;v<=m;v++){
        if(map[u][v]>0 && dep[v]==dep[u]+1 && (tmp=DFS(v,min(mi,map[u][v]))) ) {
            map[u][v]-=tmp;  ///正向增加
            map[v][u]+=tmp;  ///反向减少
            return tmp;
        }
    }
    return 0;
}

int Dinic(){
    int ans=0,tmp;
    while(BFS()){
        while(1){ ///多路增广
            tmp=DFS(src,des);
            if(!tmp) break;
            ans+=tmp;
        }
    }
    return ans;
}

int main(){
    while(~scanf("%d%d",&n,&m)){
        memset(map,0,sizeof(map));
        int u,v,w;
        for(int i=0;i<n;i++){
            scanf("%d%d%d",&u,&v,&w);
            map[u][v]+=w;   //防止有重边
        }
        src=1,des=m;
        printf("%d\n",Dinic());
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/tianwei0822/article/details/80077634
今日推荐