This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub AlexanderNekrasov/Youthful-Passion-Fruit-teambook
/**
* Author: Alexey Vasilyev
* Date: ?
* Description: Min cost with potentials
* Time: O(?)
*/
struct MCMF {
struct edge {
int a, b, cap, cost;
};
vector<edge> e;
vector<vector<int>> g;
vector<ll> po;
int s, t;
int n;
void init(int N, int S, int T) {
s = S, t = T, n = N;
g.resize(N);
e.clear();
}
void addedge(int a, int b, int cap, int cost) {
g[a].pbc(e.size());
e.pbc({a, b, cap, cost});
g[b].pbc(e.size());
e.pbc({b, a, 0, -cost});
}
void calc_p() {
po.assign(n, INF);
vector<int> inq(n);
queue<int> q;
q.push(s);
po[s] = 0;
while (!q.empty()) {
int v = q.front();
q.pop();
inq[v] = 0;
for (auto i : g[v]) {
if (po[e[i].b] > po[v] + e[i].cost && e[i].cap) {
po[e[i].b] = po[v] + e[i].cost;
if (!inq[e[i].b]) q.push(e[i].b);
inq[e[i].b] = 1;
}
}
}
}
ll getcost(int k) {
calc_p();
int flow = 0;
ll cost = 0;
while (flow < k) {
vector<ll> d(n, INF);
vector<int> pr(n);
d[s] = 0;
set<pair<ll, int>> q;
q.insert(mp(0ll, s));
while (q.size()) {
int v = q.begin()->second;
q.erase(q.begin());
for (int i : g[v]) {
int u = e[i].b;
if (e[i].cap && d[u] > d[v] + e[i].cost + po[v] - po[e[i].b]) {
q.erase(mp(d[u], u));
d[u] = d[v] + e[i].cost + po[v] - po[e[i].b];
q.insert(mp(d[u], u));
pr[u] = i;
}
}
}
if (d[t] == INF) return INF;
for (int i = 0; i < n; ++i) {
if (d[i] != INF) po[i] += d[i];
}
int gf = k - flow;
int v = t;
while (v != s) {
int id = pr[v];
chkmin(gf, e[id].cap);
v = e[id].a;
}
v = t;
while (v != s) {
int id = pr[v];
e[id].cap -= gf;
e[id ^ 1].cap += gf;
cost += 1ll * e[id].cost * gf;
v = e[id].a;
}
flow += gf;
}
return cost;
}
};
#line 1 "graph/MCMFfast.cpp"
/**
* Author: Alexey Vasilyev
* Date: ?
* Description: Min cost with potentials
* Time: O(?)
*/
struct MCMF {
struct edge {
int a, b, cap, cost;
};
vector<edge> e;
vector<vector<int>> g;
vector<ll> po;
int s, t;
int n;
void init(int N, int S, int T) {
s = S, t = T, n = N;
g.resize(N);
e.clear();
}
void addedge(int a, int b, int cap, int cost) {
g[a].pbc(e.size());
e.pbc({a, b, cap, cost});
g[b].pbc(e.size());
e.pbc({b, a, 0, -cost});
}
void calc_p() {
po.assign(n, INF);
vector<int> inq(n);
queue<int> q;
q.push(s);
po[s] = 0;
while (!q.empty()) {
int v = q.front();
q.pop();
inq[v] = 0;
for (auto i : g[v]) {
if (po[e[i].b] > po[v] + e[i].cost && e[i].cap) {
po[e[i].b] = po[v] + e[i].cost;
if (!inq[e[i].b]) q.push(e[i].b);
inq[e[i].b] = 1;
}
}
}
}
ll getcost(int k) {
calc_p();
int flow = 0;
ll cost = 0;
while (flow < k) {
vector<ll> d(n, INF);
vector<int> pr(n);
d[s] = 0;
set<pair<ll, int>> q;
q.insert(mp(0ll, s));
while (q.size()) {
int v = q.begin()->second;
q.erase(q.begin());
for (int i : g[v]) {
int u = e[i].b;
if (e[i].cap && d[u] > d[v] + e[i].cost + po[v] - po[e[i].b]) {
q.erase(mp(d[u], u));
d[u] = d[v] + e[i].cost + po[v] - po[e[i].b];
q.insert(mp(d[u], u));
pr[u] = i;
}
}
}
if (d[t] == INF) return INF;
for (int i = 0; i < n; ++i) {
if (d[i] != INF) po[i] += d[i];
}
int gf = k - flow;
int v = t;
while (v != s) {
int id = pr[v];
chkmin(gf, e[id].cap);
v = e[id].a;
}
v = t;
while (v != s) {
int id = pr[v];
e[id].cap -= gf;
e[id ^ 1].cap += gf;
cost += 1ll * e[id].cost * gf;
v = e[id].a;
}
flow += gf;
}
return cost;
}
};