网络流入门
Posted uid001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流入门相关的知识,希望对你有一定的参考价值。
求最大流一般采用Ford-Fulkerson算法, 即每次从残量网络中任选一条增广路来增广, 直到没有增广路为止.
FF算法最坏复杂度是$O(E|f^*|)$, FF算法的一个优化是EK算法, 每次用bfs选择一条最短的增广路来增广, 可以证明复杂度是$O(VE^2)$, 代码如下
int n, m, s, t; struct _ {int from,to,w;}; vector<_> E; vector<int> g[N]; int a[N], pre[N]; void add(int x, int y, int w) { g[x].pb(E.size()); E.pb({x,y,w}); } int Maxflow(int s, int t) { int ans = 0; for (; ; ) { REP(i,1,n) a[i] = 0; queue<int> q; q.push(s); a[s] = INF; while (!q.empty()) { int x = q.front();q.pop(); for (auto &t:g[x]) { auto &e = E[t]; if (!a[e.to]&&e.w>0) { pre[e.to] = t; a[e.to] = min(a[x], e.w); q.push(e.to); } } if (a[t]) break; } if (!a[t]) break; for (int u=t; u!=s; u=E[pre[u]].from) { E[pre[u]].w -= a[t]; E[pre[u]^1].w += a[t]; } ans += a[t]; } return ans; } int main() { scanf("%d%d%d%d", &n, &m, &s, &t); REP(i,1,m) { int u, v, w; scanf("%d%d%d", &u, &v, &w); add(u,v,w),add(v,u,0); } printf("%d\n", Maxflow(s,t)); }
最小费用最大流问题, 每个边上通过单位流量有一定费用, 将bfs改为spfa即可, 复杂度$O(V^2E^2)$, 也可以用dijkstra优化, 复杂度$O(VE(E+VlogV))$
const int N = 3e5+10; int n, m, s, t; struct _ {int from,to,w,f;}; vector<_> E; vector<int> g[N]; int a[N], pre[N], inq[N], d[N]; int max_flow, min_cost; void add(int x, int y, int w, int f) { g[x].pb(E.size()); E.pb({x,y,w,f}); } queue<int> q; void MaxflowMincost(int s, int t) { for (; ; ) { REP(i,0,n) a[i]=d[i]=INF,inq[i]=0; while (q.size()) q.pop(); q.push(s); a[s] = INF, d[s] = 0; while (!q.empty()) { int x = q.front();q.pop(); inq[x] = 0; for (auto &t:g[x]) { auto &e = E[t]; if (e.w>0&&d[e.to]>d[x]+e.f) { d[e.to]=d[x]+e.f; pre[e.to] = t; a[e.to] = min(a[x], e.w); if (!inq[e.to]) { inq[e.to]=1; q.push(e.to); } } } } if (a[t]==INF) break; for (int u=t; u!=s; u=E[pre[u]].from) { E[pre[u]].w -= a[t]; E[pre[u]^1].w += a[t]; } max_flow += a[t]; min_cost += a[t]*d[t]; } } int main() { scanf("%d%d%d%d", &n, &m, &s, &t); REP(i,1,m) { int u, v, w, f; scanf("%d%d%d%d", &u, &v, &w, &f); add(u,v,w,f),add(v,u,0,-f); } MaxflowMincost(s,t); printf("%d %d\n", max_flow, min_cost); }
以上是关于网络流入门的主要内容,如果未能解决你的问题,请参考以下文章