- ISAP
#include <iostream> #include <algorithm> #include <queue> namespace flow { const int N = 400000 + 7; const int INF = (1 << 30) - 1; struct flow { int n, m, st, ed; int lay[N], gap[N], cur[N], pre[N]; struct edge { int to, nex, cap; } e[N]; int fir[N], eid = 1; void addedge(int u, int v, int c); void addflow(int u, int v, int c); int isap(); }; void flow::addedge(int u, int v, int c) { e[++eid] = (edge){ v, fir[u], c }, fir[u] = eid; } void flow::addflow(int u, int v, int c) { addedge(u, v, c), addedge(v, u, 0); } int flow::isap() { std::queue <int> q; q.push(ed); for (int s; q.size(); ) { s = q.front(), q.pop(); for (int i = fir[s]; i; i = e[i].nex) if (!lay[e[i].to] && e[i].to != ed && e[i ^ 1].cap) lay[e[i].to] = lay[s] + 1, q.push(e[i].to); } for (int i = 1; i <= n; ++i) ++gap[lay[i]], cur[i] = fir[i]; int maxflow = 0, s = st, ok; while (lay[st] < n) { if (s == ed) { int f = INF; while (s != st) s = pre[s], f = std::min(f, e[cur[s]].cap); s = ed, maxflow += f; while (s != st) s = pre[s], e[cur[s]].cap -= f, e[cur[s] ^ 1].cap += f; } ok = 0; for (int i = cur[s]; i; i = e[i].nex) { cur[s] = i; if (lay[s] == lay[e[i].to] + 1 && e[i].cap) { pre[e[i].to] = s, s = e[i].to, ok = 1; break; } } if (ok) continue; if (!(--gap[lay[s]])) break; ++gap[++lay[s]], cur[s] = fir[s]; if (s != st) s = pre[s]; } return maxflow; } }; int n, m, st, ed; flow::flow f; int main () { scanf("%d%d%d%d", &f.n, &f.m, &f.st, &f.ed); for (int i = 1, u, v, w; i <= f.m; ++i) scanf("%d%d%d", &u, &v, &w), f.addflow(u, v, w); printf("%d\n", f.isap()); return 0; }
- SPFA
#include <iostream> #include <queue> using i64 = long long; namespace flow { const int N = 5000 + 7, M = 50000 + 7; const i64 INF = 1ll << 30 - 1; struct flow { int n, st, ed; i64 mincost, maxflow; int cur[N], vis[N]; i64 dis[N]; struct edge { int to, nex; i64 cap, wei; } e[M << 1]; int fir[N], eid = 1; void addedge(int u, int v, i64 c, i64 w); void addflow(int u, int v, i64 c, i64 w); i64 dinic(); int bfs(); i64 dfs(int s, i64 f); }; void flow::addedge(int u, int v, i64 c, i64 w) { e[++eid] = (edge){ v, fir[u], c, w }, fir[u] = eid; } void flow::addflow(int u, int v, i64 c, i64 w) { addedge(u, v, c, w), addedge(v, u, 0, -w); } i64 flow::dinic() { maxflow = 0, mincost = 0; for (i64 f; bfs(); ) while (1) { if (!(f = dfs(st, INF))) break; maxflow += f, mincost += f * dis[st]; } return mincost; } int flow::bfs() { std::fill(dis + 1, dis + n + 1, INF); std::fill(vis + 1, vis + n + 1, 0); for (int i = 1; i <= n; ++i) cur[i] = fir[i]; dis[ed] = 0, vis[ed] = 1; std::queue <int> q; q.push(ed); for (int s; q.size(); ) { s = q.front(), q.pop(); for (int i = fir[s]; i; i = e[i].nex) if (e[i ^ 1].cap && dis[e[i].to] > dis[s] - e[i].wei) { dis[e[i].to] = dis[s] - e[i].wei; if (!vis[e[i].to]) vis[e[i].to] = 1, q.push(e[i].to); } vis[s] = 0; } return dis[st] < INF; } i64 flow::dfs(int s, i64 f) { if (s == ed) return f; vis[s] = 1; i64 t, u = 0; for (int i = cur[s]; i; i = e[i].nex) { cur[s] = i; if (!vis[e[i].to] && e[i].cap && dis[s] == dis[e[i].to] + e[i].wei) { t = dfs(e[i].to, std::min(f - u, e[i].cap)); e[i].cap -= t, e[i ^ 1].cap += t; u += t; if (u == f) break; } } vis[s] = 0; return u; } }; int m; flow::flow f; int main() { scanf("%d%d%d%d", &f.n, &m, &f.st, &f.ed); for (int i = 1, u, v, c, w; i <= m; ++i) scanf("%d%d%d%d", &u, &v, &c, &w), f.addflow(u, v, c, w); f.dinic(); printf("%lld %lld\n", f.maxflow, f.mincost); return 0; }
来源:https://www.cnblogs.com/Ryedii-blog/p/12180329.html