-
Notifications
You must be signed in to change notification settings - Fork 108
/
Min Cost Max Flow 3.cpp
67 lines (61 loc) · 2.29 KB
/
Min Cost Max Flow 3.cpp
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
// This gave AC for CF 813D Two Melodies but the other one was TLE
// By sgtlaugh
// flow[i] contains the amount of flow in i-th edge
namespace mcmf{
const int MAX = 1000010;
const int INF = 1 << 25;
int cap[MAX], flow[MAX], cost[MAX], dis[MAX];
int n, m, s, t, Q[10000010], adj[MAX], link[MAX], last[MAX], from[MAX], visited[MAX];
void init(int nodes, int source, int sink){
m = 0, n = nodes, s = source, t = sink;
for (int i = 0; i <= n; i++) last[i] = -1;
}
void addEdge(int u, int v, int c, int w){
adj[m] = v, cap[m] = c, flow[m] = 0, cost[m] = +w, link[m] = last[u], last[u] = m++;
adj[m] = u, cap[m] = 0, flow[m] = 0, cost[m] = -w, link[m] = last[v], last[v] = m++;
}
bool spfa(){
int i, j, x, f = 0, l = 0;
for (i = 0; i <= n; i++) visited[i] = 0, dis[i] = INF;
dis[s] = 0, Q[l++] = s;
while (f < l){
i = Q[f++];
for (j = last[i]; j != -1; j = link[j]){
if (flow[j] < cap[j]){
x = adj[j];
if (dis[x] > dis[i] + cost[j]){
dis[x] = dis[i] + cost[j], from[x] = j;
if (!visited[x]){
visited[x] = 1;
if (f && rand() & 7) Q[--f] = x;
else Q[l++] = x;
}
}
}
}
visited[i] = 0;
}
return (dis[t] != INF);
}
// we can return all the flow values for each edge from this function
// vi solve()
pair <int, int> solve(){
int i, j;
int mincost = 0, maxflow = 0;
while (spfa()){
int aug = INF;
for (i = t, j = from[i]; i != s; i = adj[j ^ 1], j = from[i]){
aug = min(aug, cap[j] - flow[j]);
}
for (i = t, j = from[i]; i != s; i = adj[j ^ 1], j = from[i]){
flow[j] += aug, flow[j ^ 1] -= aug;
}
maxflow += aug, mincost += aug * dis[t];
}
// edges are indexed from 0 to m
// vi ret(flow,flow+m)
// to find flow of a specific edge, we just noticed that flow[2*i] contains
// the flow amount in i-th edge
return make_pair(mincost, maxflow);
}
}