-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathMinCostFlow.cpp
62 lines (62 loc) · 1.67 KB
/
MinCostFlow.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
struct MinCostMaxFlow{
typedef int Tcost;
static const int MAXV = 20010;
static const int INFf = 1000000;
static const Tcost INFc = 1e9;
struct Edge{
int v, cap;
Tcost w;
int rev;
Edge(){}
Edge(int t2, int t3, Tcost t4, int t5)
: v(t2), cap(t3), w(t4), rev(t5) {}
};
int V, s, t;
vector<Edge> g[MAXV];
void init(int n, int _s, int _t){
V = n; s = _s; t = _t;
for(int i = 0; i <= V; i++) g[i].clear();
}
void addEdge(int a, int b, int cap, Tcost w){
g[a].push_back(Edge(b, cap, w, (int)g[b].size()));
g[b].push_back(Edge(a, 0, -w, (int)g[a].size()-1));
}
Tcost d[MAXV];
int id[MAXV], mom[MAXV];
bool inqu[MAXV];
queue<int> q;
pair<int,Tcost> solve(){
int mxf = 0; Tcost mnc = 0;
while(1){
fill(d, d+1+V, INFc);
fill(inqu, inqu+1+V, 0);
fill(mom, mom+1+V, -1);
mom[s] = s;
d[s] = 0;
q.push(s); inqu[s] = 1;
while(q.size()){
int u = q.front(); q.pop();
inqu[u] = 0;
for(int i = 0; i < (int) g[u].size(); i++){
Edge &e = g[u][i];
int v = e.v;
if(e.cap > 0 && d[v] > d[u]+e.w){
d[v] = d[u]+e.w;
mom[v] = u;
id[v] = i;
if(!inqu[v]) q.push(v), inqu[v] = 1;
} } }
if(mom[t] == -1) break ;
int df = INFf;
for(int u = t; u != s; u = mom[u])
df = min(df, g[mom[u]][id[u]].cap);
for(int u = t; u != s; u = mom[u]){
Edge &e = g[mom[u]][id[u]];
e.cap -= df;
g[e.v][e.rev].cap += df;
}
mxf += df;
mnc += df*d[t];
}
return {mxf,mnc};
} }flow;