最大流:
int s,t;
int h[N],e[M],f[M],ne[M],idx;
int q[N],d[N],cur[N];
void add_edge_ (int a,int b,int c) {
e[idx] = b;
f[idx] = c;
ne[idx] = h[a];
h[a] = idx++;
}
void add_edge (int a,int b,int c) {
add_edge_ (a,b,c),add_edge_ (b,a,0);
}
bool BFS () {
int hh = 0,tt = -1;
q[++tt] = s;
memset (d,-1,sizeof (d));
d[s] = 1;
cur[s] = h[s];
while (hh <= tt) {
int u = q[hh++];
for (int i = h[u];~i;i = ne[i]) {
int v = e[i];
if (d[v] == -1 && f[i]) {
d[v] = d[u] + 1;
cur[v] = h[v];
if (v == t) return true;
q[++tt] = v;
}
}
}
return false;
}
int max_flow (int u,int lim) {
if (u == t) return lim;
int flow = 0;
for (int i = cur[u];~i && flow < lim;i = ne[i]) {
cur[u] = i;
int v = e[i];
if (d[v] == d[u] + 1 && f[i]) {
int tmp = max_flow (v,min (lim - flow,f[i]));
if (!tmp) d[v] = -1;
f[i] -= tmp,f[i ^ 1] += tmp,flow += tmp;
}
}
return flow;
}
int dinic () {
int ans = 0,flow;
while (BFS ()) {
while (flow = max_flow (s,INF)) ans += flow;
}
return ans;
}
最小费用最大流:
int s,t;
int h[N],e[M],ne[M],f[M],w[M],idx;
int q[N],d[N],flow[N],pre[N];
bool st[N];
void add_edge_ (int a,int b,int c,int d) {
e[idx] = b;
f[idx] = c;
w[idx] = d;
ne[idx] = h[a];
h[a] = idx++;
}
void add_edge (int a,int b,int c,int d) {
add_edge_ (a,b,c,d),add_edge_ (b,a,0,-d);
}
bool SPFA () {
int hh = 0,tt = 0;
q[tt++] = s;
memset (d,-0x3f,sizeof (d));
d[s] = 0;
memset (flow,0,sizeof (flow));
flow[s] = INF;
while (hh != tt) {
int u = q[hh++];
if (hh == N) hh = 0;
st[u] = false;
for (int i = h[u];~i;i = ne[i]) {
int v = e[i];
if (f[i] && d[v] < d[u] + w[i]) {
d[v] = d[u] + w[i];
flow[v] = min (flow[u],f[i]);
pre[v] = i;
if (!st[v]) {
q[tt++] = v;
if (tt == N) tt = 0;
st[v] = true;
}
}
}
}
return flow[t] > 0;
}
int EK () {
int ans = 0;
while (SPFA ()) {
ans += d[t] * flow[t];
for (int i = t;i != s;i = e[pre[i] ^ 1]) f[pre[i]] -= flow[t],f[pre[i] ^ 1] += flow[t];
}
return ans;
}
标签:常用,idx,int,tt,flow,add,edge,模板
From: https://www.cnblogs.com/incra/p/18076674