1. 程式人生 > 實用技巧 >【模板】網路最大流(EK、Dinic、ISAP)(網路流)/洛谷P3376

【模板】網路最大流(EK、Dinic、ISAP)(網路流)/洛谷P3376

題目連結

https://www.luogu.com.cn/problem/P3376

題目大意

輸入格式
第一行包含四個正整數 \(n,m,s,t\),分別表示點的個數、有向邊的個數、源點序號、匯點序號。
接下來\(m\)行,每行包含三個正整數 \(u_i,v_i,w_i\),表示第 \(i\) 條有向邊從 \(u_i\) 出發,到達 \(v_i\),邊權為 \(w_i\)(即該邊最大流量為 \(w_i\) )。
輸出格式
一行,包含一個正整數,即為該網路的最大流。

題目解析

參考程式碼

\(EK\)

#include <bits/stdc++.h>
using namespace std;
const int N = 205;
const long long INF = (1LL << 32);
struct Edge{
    int from, to;
    long long cap, flow;
};
int n, m, s, t;
long long a[N];
int p[N];
vector <Edge> e;
vector <int> G[N];

void addEdge(int from, int to, int cap, int i)
{
    e.push_back((Edge){from, to, cap, 0});
    e.push_back((Edge){to, from, 0, 0});
    G[from].push_back(i << 1);
    G[to].push_back((i << 1)+1);
}
long long maxflow()
{
    long long flow = 0;
    while (1)
    {
        memset(a, 0, sizeof(a));
        a[s] = INF;
        queue <int> q;
        q.push(s);
        while (!q.empty())
        {
            int x = q.front();
            q.pop();
            for (int i=0; i<G[x].size(); ++i)
            {
                Edge &b = e[G[x][i]];
                if (!a[b.to] && b.cap > b.flow)
                {
                    p[b.to] = G[x][i];
                    a[b.to] = min(a[x], b.cap-b.flow);
                    q.push(b.to);
                }
            }
            if (a[t]) break;
        }
        if (!a[t]) break;
        for (int u=t; u!=s; u=e[p[u]].from)
        {
            e[p[u]].flow += a[t];
            e[p[u]^1].flow -= a[t];
        }
        flow += a[t];
    }
    return flow;
}
int main()
{
    int u, v, w;
    scanf("%d%d%d%d", &n, &m, &s, &t);
    for (int i=0; i<m; ++i)
    {
        scanf("%d%d%d", &u, &v, &w);
        addEdge(u, v, w, i);
    }
    printf("%lld\n", maxflow());
    return 0;
}