[模板]网络最大流

https://www.luogu.org/problemnew/show/3376

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;
const int N = 300001;

#define oo 99999999

int n, m, S, T, now, Hi, Ti = 1;
int now_head[N], head[N], dis[N];
struct Node{
    int u, v, cap, nxt;
}G[N << 1];

inline int read(){
    int x = 0; char c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x;
}

struct Queue{
    int sz[N << 2];
    void pop(){Hi ++;}
    void push(int a) {sz[++ Ti] = a;}
    int front() {return sz[Hi];}
    bool empty() {return !(Ti >= Hi);}
};
Queue Q;

inline void add(int u, int v, int cap){
    G[now].u = u; G[now].v = v; G[now].cap = cap; G[now].nxt = head[u]; head[u] = now ++;
}

inline bool bfs(){
    for(int i = 1; i <= n; i ++) dis[i] = -1, now_head[i] = head[i];
    dis[S] = 0;
    while(!Q.empty()) Q.pop();
    Q.push(S);
    while(!Q.empty()){
        int topp = Q.front();
        Q.pop();
        for(int i = head[topp]; ~ i; i = G[i].nxt){
            int v = G[i].v;
            if(dis[v] == -1 && G[i].cap > 0){
                dis[v] = dis[topp] + 1;
                if(v == T) return 1;
                Q.push(v);
            }
        }
    }
    return 0;
}

int dfs(int now, int flow){
    if(now == T) return flow;
    int f, ret = 0;
    for(int & i = now_head[now]; ~ i; i = G[i].nxt){
        int v = G[i].v;
        if(dis[v] == dis[now] + 1 && G[i].cap > 0){
            f = dfs(v, min(G[i].cap, flow - ret));
            if(f){
                G[i].cap -= f;
                G[i ^ 1].cap += f;
                ret += f;
                if(ret == flow) break;
            }
        }
    }
    if(ret != flow) dis[now] = -1;
    return ret;
}

inline int Dinic(){
    int answer = 0;
    while(bfs()) answer += dfs(S, oo);
    return answer;
}

int main()
{
    n = read(); m = read(); S = read(); T = read();
    for(int i = 1; i <= n; i ++) head[i] = -1; 
    for(int i = 1; i <= m; i ++) {
        int u = read(), v = read(), cap = read();
        add(u, v, cap); add(v, u, 0);
    }
    
    printf("%d", Dinic());
    
    return 0;
}

 

posted @ 2017-12-12 20:35  xayata  阅读(180)  评论(0编辑  收藏  举报