【模板】網路最大流(EK、Dinic、ISAP)(網路流)/洛谷P3376
阿新 • • 發佈:2020-08-26
題目連結
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; }