最大流模板大全

四种算法随便选!!!

#include <bits/stdc++.h>
#define int long long
using namespace std ;
const int MAXN = 1205 ;
const long long INF = (1LL << 62) ;
struct Edge { int to , cap , rev ; } ;
vector<Edge> g[MAXN] ;
int n , m , s , t ;
const int MAXM = 120000 + 5 ;
int eu[MAXM] , ev[MAXM] ; long long ew[MAXM] ;
int max (int a , int b) {
    return a > b ? a : b ;
}
void build_graph () {
    for (int i = 1 ; i <= n ; i ++) {
        g[i].clear() ;
    }
    int avg = max(4 , (int) (m / max(1, n)) + 2) ;
    for (int i = 1 ; i <= n ; i ++) g[i].reserve(avg) ;
    for (int i = 1 ; i <= m ; i ++) {
        int u = eu[i] , v = ev[i] ; long long w = ew[i] ;
        g[u].push_back({v , (int) w , (int) g[v].size()}) ;
        g[v].push_back({u , 0 , (int) g[u].size() - 1}) ;
    }
}

/* ------------------ Dinic ------------------ */
int disD[MAXN] , curD[MAXN] ;
bool bfsD () {
    memset(disD , -1 , sizeof(disD)) ;
    queue<int> q ;
    disD[s] = 0 ; q.push(s) ;
    while (! q.empty()) {
        int u = q.front() ; q.pop() ;
        for (auto &e : g[u]) {
            if (e.cap > 0 && disD[e.to] == -1) {
                disD[e.to] = disD[u] + 1 ;
                q.push(e.to) ;
            }
        }
    }
    return disD[t] != -1 ;
}
int dfsD (int u , int flow) {
    if (! flow) return 0 ;
    if (u == t) return flow ;
    for (int &i = curD[u] ; i < (int) g[u].size() ; i ++) {
        Edge &e = g[u][i] ;
        if (e.cap > 0 && disD[e.to] == disD[u] + 1) {
            int got = dfsD(e.to , (int) min((long long)flow , (long long)e.cap)) ;
            if (got > 0) {
                e.cap -= got ;
                g[e.to][e.rev].cap += got ;
                return got ;
            }
        }
    }
    return 0 ;
}
long long run_dinic () {
    long long flow = 0 ;
    while (bfsD()) {
        memset(curD , 0 , sizeof(curD)) ;
        while (int pushed = dfsD(s , (int)INF)) flow += pushed ;
    }
    return flow ;
}

/* ------------------ ISAP ------------------ */
int disI[MAXN] , curI[MAXN] , gapI[MAXN] ;
void bfs_from_t () {
    for (int i = 1 ; i <= n ; i ++) disI[i] = -1 ;
    queue<int> q ;
    disI[t] = 0 ; q.push(t) ;
    while (! q.empty()) {
        int u = q.front() ; q.pop() ;
        for (auto &e : g[u]) {
            if (g[e.to][e.rev].cap > 0 && disI[e.to] == -1) {
                disI[e.to] = disI[u] + 1 ;
                q.push(e.to) ;
            }
        }
    }
    for (int i = 1 ; i <= n ; i ++) if (disI[i] == -1) disI[i] = n ;
    for (int i = 0 ; i <= n ; i ++) gapI[i] = 0 ;
    for (int i = 1 ; i <= n ; i ++) gapI[disI[i]] ++ ;
}
int dfsI (int u , int flow) {
    if (u == t) return flow ;
    int used = 0 ;
    for (int &i = curI[u] ; i < (int) g[u].size() ; i ++) {
        Edge &e = g[u][i] ;
        if (e.cap > 0 && disI[e.to] + 1 == disI[u]) { 
            int got = dfsI(e.to , (int) min((long long)(flow - used) , (long long)e.cap)) ;
            if (got > 0) {
                e.cap -= got ;
                g[e.to][e.rev].cap += got ;
                used += got ;
                if (used == flow) return used ;
            }
        }
    }
    gapI[disI[u]] -- ;
    if (gapI[disI[u]] == 0) { 
        disI[s] = n ;
    }
    disI[u] ++ ;
    if (disI[u] > n) disI[u] = n ;
    gapI[disI[u]] ++ ;
    curI[u] = 0 ;
    return used ;
}
long long run_isap () {
    bfs_from_t() ;
    memset(curI , 0 , sizeof(curI)) ;
    long long flow = 0 ;
    while (disI[s] < n) flow += dfsI(s , (int)INF) ;
    return flow ;
}

/* ------------------ ID ------------------ */
int disID[MAXN] , curID[MAXN] ;
bool bfsID () {
    memset(disID , -1 , sizeof(disID)) ;
    queue<int> q ;
    disID[s] = 0 ; q.push(s) ;
    while (! q.empty()) {
        int u = q.front() ; q.pop() ;
        for (auto &e : g[u]) if (e.cap > 0 && disID[e.to] == -1) {
            disID[e.to] = disID[u] + 1 ;
            q.push(e.to) ;
        }
    }
    return disID[t] != -1 ;
}
int dfsID (int u , int flow) {
    if (! flow) return 0 ;
    if (u == t) return flow ;
    for (int &i = curID[u] ; i < (int) g[u].size() ; i ++) {
        Edge &e = g[u][i] ;
        if (e.cap > 0 && disID[e.to] == disID[u] + 1) {
            int got = dfsID(e.to , (int) min((long long)flow , (long long)e.cap)) ;
            if (got > 0) {
                e.cap -= got ;
                g[e.to][e.rev].cap += got ;
                return got ;
            }
        }
    }
    disID[u] = -1 ;
    return 0 ;
}
long long run_idinic () {
    long long flow = 0 ;
    while (bfsID()) {
        memset(curID , 0 , sizeof(curID)) ;
        while (int pushed = dfsID(s , (int)INF)) flow += pushed ;
    }
    return flow ;
}

/* ------------------ HLPP ------------------ */
int hH[MAXN] , ex[MAXN] , curH[MAXN] ;
vector<int> bucket[2 * MAXN] ; // 高度可能到 2*n
int maxH ;
long long run_hlpp () {
    // init
    for (int i = 0 ; i <= 2 * n ; i ++) bucket[i].clear() ;
    for (int i = 1 ; i <= n ; i ++) { hH[i] = 0 ; ex[i] = 0 ; curH[i] = 0 ; }
    // preflow
    hH[s] = n ;
    for (auto &e : g[s]) {
        if (e.cap > 0) {
            int f = e.cap ;
            e.cap = 0 ;
            g[e.to][e.rev].cap += f ;
            ex[e.to] += f ;
        }
    }
    maxH = 0 ;
    for (int i = 1 ; i <= n ; i ++) if (i != s && i != t && ex[i] > 0) {
        bucket[hH[i]].push_back(i) ;
        maxH = max(maxH , hH[i]) ;
    }
    // 主循环:从最高桶取点 discharge
    while (maxH >= 0) {
        if (bucket[maxH].empty()) { maxH -- ; continue ; }
        int u = bucket[maxH].back() ; bucket[maxH].pop_back() ;
        // discharge u
        while (ex[u] > 0) {
            if (curH[u] < (int) g[u].size()) {
                Edge &e = g[u][curH[u]] ;
                if (e.cap > 0 && hH[u] == hH[e.to] + 1) {
                    int f = (int) min((long long)ex[u] , (long long)e.cap) ;
                    int prev = ex[e.to] ;
                    e.cap -= f ;
                    g[e.to][e.rev].cap += f ;
                    ex[u] -= f ;
                    ex[e.to] += f ;
                    if (e.to != s && e.to != t && prev == 0) {
                        bucket[hH[e.to]].push_back(e.to) ;
                        maxH = max(maxH , hH[e.to]) ;
                    }
                } else curH[u] ++ ;
            } else {
                // relabel
                int minh = INT_MAX ;
                for (auto &e : g[u]) if (e.cap > 0) minh = min(minh , hH[e.to]) ;
                if (minh == INT_MAX) { hH[u] = 2 * n ; } else { hH[u] = minh + 1 ; }
                curH[u] = 0 ;
            }
        }
    }
    return ex[t] ;
}

/* ------------------ 主程序和模式选择 ------------------ */
signed main () {
    ios::sync_with_stdio(false) ;
    cin.tie(NULL) ; cout.tie(NULL) ;

    int mode = 4 ; // 改 mode: 1/2/3/4
    cin >> n >> m >> s >> t ;
    for (int i = 1 ; i <= m ; i ++) {
        int uu , vv ; long long ww ;
        cin >> uu >> vv >> ww ;
        eu[i] = uu ; ev[i] = vv ; ew[i] = ww ;
    }

    build_graph() ;
    long long ans = 0 ;
    if (mode == 1) ans = run_dinic() ;
    else if (mode == 2) ans = run_isap() ;
    else if (mode == 3) ans = run_idinic() ;
    else if (mode == 4) ans = run_hlpp() ;
    cout << ans << '\n' ;
    return 0 ;
}

posted @ 2025-08-12 13:15  hanciyang  阅读(6)  评论(0)    收藏  举报