# Flow
###### tags: `Template`
## Dinic
```cpp=
struct Dinic {
struct Edge {
int t, c, r;
Edge() {}
Edge(int _t, int _c, int _r):
t(_t), c(_c), r(_r) {}
};
vector<vector<Edge>> G;
vector<int> dis, iter;
int s, t;
void init(int n) {
G.resize(n), dis.resize(n), iter.resize(n);
for(int i = 0; i < n; ++i)
G[i].clear();
}
void add(int a, int b, int c) {
G[a].eb(b, c, G[b].size());
G[b].eb(a, 0, G[a].size() - 1);
}
bool bfs() {
fill(ALL(dis), -1);
dis[s] = 0;
queue<int> que;
que.push(s);
while(!que.empty()) {
int u = que.front(); que.pop();
for(auto& e : G[u]) {
if(e.c > 0 && dis[e.t] == -1) {
dis[e.t] = dis[u] + 1;
que.push(e.t);
}
}
}
return dis[t] != -1;
}
int dfs(int u, int cur) {
if(u == t) return cur;
for(int &i = iter[u]; i < (int)G[u].size(); ++i) {
auto& e = G[u][i];
if(e.c > 0 && dis[u] + 1 == dis[e.t]) {
int ans = dfs(e.t, min(cur, e.c));
if(ans > 0) {
G[e.t][e.r].c += ans;
e.c -= ans;
return ans;
}
}
}
return 0;
}
int flow(int a, int b) {
s = a, t = b;
int ans = 0;
while(bfs()) {
fill(ALL(iter), 0);
int tmp;
while((tmp = dfs(s, INF)) > 0)
ans += tmp;
}
return ans;
}
};
```
## MCMF
```cpp=
struct MCMF {
struct Edge {
int to, cap, rev;
ll cost;
Edge() {}
Edge(int _to, int _cap, int _rev, ll _cost) :
to(_to), cap(_cap), rev(_rev), cost(_cost) {}
};
static const int N = 2000;
vector<Edge> G[N];
int n, s, t;
void init(int _n, int _s, int _t) {
n = _n, s = _s, t = _t;
for(int i = 0; i <= n; ++i)
G[i].clear();
}
void add_edge(int from, int to, int cap, ll cost) {
G[from].eb(to, cap, (int)G[to].size(), cost);
G[to].eb(from, 0, (int)G[from].size() - 1, -cost);
}
bool vis[N];
int iter[N];
ll dis[N];
bool SPFA() {
for(int i = 0; i <= n; ++i)
vis[i] = 0, dis[i] = LINF;
dis[s] = 0; vis[s] = 1;
queue<int> que; que.push(s);
while(!que.empty()) {
int u = que.front(); que.pop();
vis[u] = 0;
for(auto& e : G[u]) if(e.cap > 0 && dis[e.to] > dis[u] + e.cost) {
dis[e.to] = dis[u] + e.cost;
if(!vis[e.to]) {
que.push(e.to);
vis[e.to] = 1;
}
}
}
return dis[t] != LINF;
}
int dfs(int u, int cur) {
if(u == t) return cur;
int ret = 0; vis[u] = 1;
for(int &i = iter[u]; i < (int)G[u].size(); ++i) {
auto &e = G[u][i];
if(e.cap > 0 && dis[e.to] == dis[u] + e.cost && !vis[e.to]) {
int tmp = dfs(e.to, min(cur, e.cap));
e.cap -= tmp;
G[e.to][e.rev].cap += tmp;
cur -= tmp;
ret += tmp;
if(cur == 0) {
vis[u] = 0;
return ret;
}
}
}
vis[u] = 0;
return ret;
}
pair<int, ll> flow() {
int flow = 0; ll cost = 0;
while(SPFA()) {
memset(iter, 0, sizeof(iter));
int tmp = dfs(s, INF);
flow += tmp, cost += tmp * dis[t];
}
return {flow, cost};
}
};
```