- 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