-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMinCostMaxFlow
78 lines (71 loc) · 1.78 KB
/
MinCostMaxFlow
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
const ll maxnodes = 10005;
ll nodes = maxnodes, src, dest;
ll dist[maxnodes], exist[maxnodes];
pii par[maxnodes];
struct Edge
{
ll to, rev;
ll f, cap, cost;
};
vector<Edge> g[maxnodes];
void addEdge(ll s, ll t, ll cap, ll cost)
{
Edge a = {t, g[t].size(), 0, cap, cost};
Edge b = {s, g[s].size(), 0, 0, -cost};
g[s].push_back(a);
g[t].push_back(b);
}
bool spfa()
{
fill(dist, dist + nodes, oo);
fill(exist, exist + nodes, 0);
dist[src] = 0, exist[src] = 1;
queue <ll> q;
q.push(src);
while(!q.empty()) {
ll u = q.front();
q.pop();
exist[u] = 0;
for(ll i = 0; i < g[u].size(); i++) {
Edge e = g[u][i] ;
if(dist[e.to] > dist[u] + e.cost && e.f < e.cap) {
dist[e.to] = dist[u] + e.cost;
par[e.to] = {u, i};
if(!exist[e.to]) {
q.push(e.to);
exist[e.to] = 1;
}
}
}
}
return dist[dest] != oo;
}
pii minCostMaxFlow(ll _src, ll _dest)
{
src = _src;
dest = _dest;
pii result = {0,0};
while (spfa())
{
ll cur = _dest, flow = oo;
while(cur != _src) {
ll p = par[cur].first;
Edge e = g[p][ par[cur].second ];
flow = min(flow, e.cap - e.f);
cur = p;
}
result.first += flow;
cur = _dest;
while(cur != _src) {
ll p = par[cur].first;
Edge &e = g[p][ par[cur].second ];
e.f += flow;
g[e.to][e.rev].f -= flow;
result.second += flow * e.cost;
cur = p;
}
}
return result;
}
// addEdge(u, v, C, cst); edge from u to v. Capacity=C, Cost=cst.
// minCostMaxFlow(s, t); min cost max flow from s to t