int MFdfs(int u, int t, int f) { if (u == t) return f; for(int &i = curAdj[u]; i < adj[u].size(); ++i) { int ar = adj[u][i], v = dest[ar]; if (d[v] != d[u]+1 || capres(ar) == 0) continue; int tmpF = MFdfs(v, t, min(f, capres(ar))); if (tmpF) { flow[ar] += tmpF; flow[inv(ar)] -= tmpF; return tmpF; } } return 0; }
double mincostflow() { pot.resize(sz(adj)); flow.resize(sz(dest)); for (delta = 0x40000000; delta > 0; delta /= 2) { fu(a, sz(dest)) { int u = orig(a), v = dest[a]; if (capres(a) >= delta && cmp(rescost(a)) < 0) { imb[u] -= capres(a); imb[v] += capres(a); flow[inv(a)] -= capres(a); flow[a] += capres(a); } } while (dijkstra()); }
bool dijkstra() { priority_queue<pair<double, pair<int, int> > > q; vi ent(sz(adj), -2); vd dist(sz(adj), INF); fu(u, sz(adj)) if (imb[u] >= delta) q.push(make_pair(0.0, make_pair(u, -1))); while (!q.empty()) { int u = q.top().second.first, f = q.top().second.second; double d = -q.top().first; q.pop(); if (ent[u] != -2) continue; dist[u] = d; ent[u] = f; for (int a : adj[u]) if (capres(a) >= delta) q.push(make_pair(-(dist[u] + rescost(a)), make_pair(dest[a], a))); } fu(u, sz(adj)) if (ent[u] != -2 && imb[u] <= -delta) { fu(v, sz(adj)) pot[v] += dist[v]; for (int a = ent[u]; a != -1; a = ent[orig(a)]) { flow[a] += delta; flow[inv(a)] -= delta; imb[dest[a]] += delta; imb[orig(a)] -= delta; } return true; } return false; }
int avanca(int no, int ar) { int viz = dest[ar]; ent[viz] = ar; lim[viz] = min(lim[no], capres(ar)); return viz; }
int admissivel(int no) { while (padj[no] < nadj[no]) { int ar = adj[no][padj[no]]; if (nivel[no] == nivel[dest[ar]] + 1 && capres(ar) > 0) return ar; padj[no]++; } padj[no] = 0; return NULO; }
bool MFbfs(int ini, int end) { d = vi(n, INF); curAdj = vi(n); d[ini] = 0; queue<int> Q; Q.push(ini); while (!Q.empty()) { int u = Q.front(); Q.pop(); for(auto i : adj[u]) { int v = dest[i]; if (capres(i) > 0 && d[v] == INF) { d[v] = d[u] + 1; Q.push(v); } } } return d[end] != INF; }
bool MFbfs(int s, int t) { d = vi(sz(adj), INF); curAdj = vi(sz(adj)); d[s] = 0; queue<int> Q; Q.push(s); while (!Q.empty()) { int u = Q.front(); Q.pop(); for (auto i : adj[u]) { int v = dest[i]; if (capres(i) > 0 && d[v] == INF) { d[v] = d[u] + 1; Q.push(v); } } } return d[t] != INF; }
int retrocede(int no) { int i, ar, viz, menor = NULO; if (--qtd[nivel[no]] == 0) return NULO; for (i = 0; i < nadj[no]; i++) { ar = adj[no][i]; viz = dest[ar]; if (capres(ar) <= 0) continue; if (menor == NULO || nivel[viz] < nivel[menor]) menor = viz; } if (menor != NULO) nivel[no] = nivel[menor]; qtd[++nivel[no]]++; return ((ent[no] == NULO) ? no : orig(ent[no])); }