最大流 / 最小割
const long long inf = 0x3f3f3f3f3f3f3f3f;
struct Graph {
int fst[MAXN], nxt[MAXM], to[MAXM], tot;
int now[MAXN], d[MAXN];
long long f[MAXM];
int s, t;
Graph() : tot(1) {}
void init() {
memset(fst, 0, sizeof fst);
s = t = 0;
tot = 1;
}
int add(int u, int v, long long w) {
to[++tot] = v, nxt[tot] = fst[u], fst[u] = tot, f[tot] = w;
to[++tot] = u, nxt[tot] = fst[v], fst[v] = tot, f[tot] = 0;
return tot - 1;
}
bool bfs() {
memset(d, 0, sizeof d);
memcpy(now, fst, sizeof fst);
queue<int> q; q.push(s); d[s] = 1;
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i = fst[u], v = to[i]; i; i = nxt[i], v = to[i]) if (f[i] && !d[v]) {
d[v] = d[u] + 1;
q.push(v);
}
}
return d[t];
}
long long dfs(int u, long long flow) {
if (u == t) return flow;
long long rest = flow;
for (int &i = now[u], v = to[i]; i; i = nxt[i], v = to[i]) {
if (f[i] && d[v] == d[u] + 1) {
long long k = dfs(v, min(rest, f[i]));
if (!k) d[v] = 0;
rest -= k, f[i] -= k, f[i ^ 1] += k;
}
if (!rest) break;
}
return flow - rest;
}
long long dinic() {
long long flow, maxflow = 0;
while (bfs()) while (flow = dfs(s, inf)) maxflow += flow;
return maxflow;
}
} g;
最小费用最大流
const long long INF = 0x3f3f3f3f3f3f3f3f;
struct Graph {
int fst[MAXN], now[MAXN], s, t;
long long d[MAXN], f[MAXM], c[MAXM];
int nxt[MAXM], to[MAXM], tot;
void add(int u, int v, long long w, long long d) {
to[++tot] = v, nxt[tot] = fst[u], f[tot] = w, c[tot] = d, fst[u] = tot;
to[++tot] = u, nxt[tot] = fst[v], f[tot] = 0, c[tot] = -d, fst[v] = tot;
}
Graph() : tot(1) {}
bool vis[MAXN];
bool spfa() {
memset(d, 0x3f, sizeof d);
memcpy(now, fst, sizeof fst);
queue<int> q; d[s] = 0, vis[s] = 1, q.push(s);
while (!q.empty()) {
int u = q.front(); q.pop();
vis[u] = 0;
for (int i = fst[u], v = to[i]; i; i = nxt[i], v = to[i]) {
if (f[i] && d[u] + c[i] < d[v]) {
d[v] = d[u] + c[i];
if (!vis[v]) vis[v] = 1, q.push(v);
}
}
}
return d[t] != INF;
}
long long dfs(int u, long long flow, long long &cost) {
if (u == t) return flow;
long long rest = flow;
vis[u] = 1;
for (int &i = now[u], v = to[i]; i; i = nxt[i], v = to[i]) {
if (!vis[v] && f[i] && d[v] == d[u] + c[i]) {
long long k = dfs(v, min(rest, f[i]), cost);
if (!k) d[v] = -1;
f[i] -= k, f[i ^ 1] += k, rest -= k, cost += c[i] * k;
}
if (!rest) break;
}
vis[u] = 0;
return flow - rest;
}
pair<long long, long long> dinic() {
long long flow, maxflow = 0, cost = 0;
while (spfa())
while (flow = dfs(s, INF, cost)) maxflow += flow;
return { maxflow, cost };
}
} g;
有源汇上下界最大流
const int inf = INT_MAX / 2;
struct Graph {
int fst[MAXN], nxt[MAXM], to[MAXM], f[MAXM], now[MAXN], d[MAXN], tot;
int s, t;
int in[MAXN], out[MAXN];
int ncnt; int operator()() { return ++ncnt; }
void init() {
tot = 1, ncnt = 0;
memset(fst, 0, sizeof fst);
memset(in, 0, sizeof in);
memset(out, 0, sizeof out);
}
int add(int u, int v, int l, int r) {
to[++tot] = v, f[tot] = r - l, nxt[tot] = fst[u], fst[u] = tot;
to[++tot] = u, f[tot] = 0, nxt[tot] = fst[v], fst[v] = tot;
in[v] += l, out[u] += l;
return tot - 1;
}
bool bfs() {
memset(d, 0, sizeof d);
memcpy(now, fst, sizeof fst);
queue<int> q; q.push(s); d[s] = 1;
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i = fst[u], v = to[i]; i; i = nxt[i], v = to[i]) {
if (f[i] && !d[v]) {
q.push(v);
d[v] = d[u] + 1;
if (v == t) return true;
}
}
}
return false;
}
int dfs(int u, int flow) {
if (u == t) return flow;
int rest = flow;
for (int &i = now[u], v = to[i]; i; i = nxt[i], v = to[i]) {
if (f[i] && d[v] == d[u] + 1) {
int k = dfs(v, min(rest, f[i]));
if (!k) d[v] = 0;
f[i] -= k, f[i ^ 1] += k, rest -= k;
}
if (!rest) break;
}
return flow - rest;
}
int dinic(int S, int T) {
s = S, t = T;
int flow, maxflow = 0;
while (bfs()) while (flow = dfs(S, inf)) maxflow += flow;
return maxflow;
}
int solve(int S, int T) {
int k = add(T, S, 0, inf);
int ss = ++ncnt, tt = ++ncnt;
int sum = 0;
for (int i = 1; i <= ncnt; i++) {
if (in[i] > out[i]) add(ss, i, 0, in[i] - out[i]),
sum += in[i] - out[i];
if (in[i] < out[i]) add(i, tt, 0, out[i] - in[i]);
}
if (dinic(ss, tt) != sum) return -1;
int ans = f[k ^ 1];
f[k] = f[k ^ 1] = 0;
return ans + dinic(S, T);
}
}g;
有源汇上下界最小费用可行流
const int inf = 0x3f3f3f3f;
struct Graph {
int fst[MAXN], nxt[MAXM], to[MAXM], f[MAXM], now[MAXN], d[MAXN], tot;
int c[MAXM];
bool vis[MAXN];
int s, t, in[MAXN], out[MAXN], sum;
int ncnt; int operator()() { return ++ncnt; }
void init() {
tot = 1, ncnt = 0;
memset(fst, 0, sizeof fst);
memset(in, 0, sizeof in);
memset(out, 0, sizeof out);
}
void add(int u, int v, int l, int r, int V) {
to[++tot] = v, f[tot] = r - l, nxt[tot] = fst[u], fst[u] = tot, c[tot] = V;
to[++tot] = u, f[tot] = 0, nxt[tot] = fst[v], fst[v] = tot, c[tot] = -V;
sum += l * V;
in[v] += l, out[u] += l;
}
bool spfa() {
memset(d, 0x3f, sizeof d);
memcpy(now, fst, sizeof fst);
queue<int> q; d[s] = 0, vis[s] = 1; q.push(s);
while (!q.empty()) {
int u = q.front(); q.pop(); vis[u] = 0;
for (int i = fst[u], v = to[i]; i; i = nxt[i], v = to[i]) {
if (f[i] && d[v] > d[u] + c[i]) {
d[v] = d[u] + c[i];
if (!vis[v]) vis[v] = 1, q.push(v);
}
}
}
return d[t] != inf;
}
int dfs(int u, int flow, int &cost) {
if (u == t) return flow;
int rest = flow;
vis[u] = 1;
for (int &i = now[u], v = to[i]; i; i = nxt[i], v = to[i]) {
if (!vis[v] && f[i] && d[v] == d[u] + c[i]) {
int k = dfs(v, min(rest, f[i]), cost);
if (!k) d[v] = -1;
f[i] -= k, f[i ^ 1] += k, rest -= k, cost += k * c[i];
}
if (!rest) break;
}
vis[u] = 0;
return flow - rest;
}
int solve() {
int ss = ++ncnt, tt = ++ncnt;
s = ss, t = tt;
for (int i = 1; i <= ncnt; i++) {
if (in[i] < out[i]) add(i, tt, 0, out[i] - in[i], 0);
if (in[i] > out[i]) add(ss, i, 0, in[i] - out[i], 0);
}
int flow, maxflow = 0, cost = 0;
while (spfa())
while (flow = dfs(ss, inf, cost)) maxflow += flow;
return cost + sum;
}
}g;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】