[模板] 网络最大流

dinic算法,在二分图上就是Hopcroft-Karp算法

#include<iostream>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<queue>

using namespace std;

const int MAXN=100005;
const int INF=1<<30;

int n,m,s,t;
int mxflow;

inline int rd(){
    int ret=0,f=1;char c;
    while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
    while(isdigit(c))ret=ret*10+c-'0',c=getchar();
    return ret*f;
}

struct Edge{
    int next,to,w;
}e[MAXN*10];
int ecnt=1,head[MAXN],cur[MAXN];
inline void add(int x,int y,int w){
    e[++ecnt].next = head[x];
    e[ecnt].to = y;
    e[ecnt].w = w;
    head[x] = ecnt;
}

int dis[MAXN];
bool bfs(){
    queue<int> Q;
    memset(dis,0,sizeof(dis));
    Q.push(s);dis[s]=1;
    while(!Q.empty()){
        int top=Q.front();Q.pop();
        for(int i=head[top];i;i=e[i].next){
            int v=e[i].to;
            if(dis[v]||!e[i].w) continue;
            Q.push(v);dis[v]=dis[top]+1;
        }
    }
    return dis[t];
}

int dfs(int x,int val){
    if(x==t) return val;
    int used=0,tmp;
    for(int i=cur[x];i;i=e[i].next){
        int v=e[i].to;
        if(dis[v]!=dis[x]+1) continue;//
        tmp=dfs(v,min(val-used,e[i].w));
        used+=tmp;
        e[i].w-=tmp;
        e[i^1].w+=tmp;
        if(e[i].w) cur[x]=i;
        if(val==used) return val;
    }
    if(!used) dis[x]=0;
    return used;
}

void dinic(){
    while(bfs()){
        memcpy(cur,head,sizeof(head));
        mxflow+=dfs(s,INF);
    }
}

int main(){
    n=rd();m=rd();
    s=rd();t=rd();
    int x,y,w;
    for(int i=1;i<=m;i++){
        x=rd();y=rd();w=rd();
        add(x,y,w);
        add(y,x,0);
    }
    dinic();
    printf("%d\n",mxflow);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/gh0stcai/article/details/80309943