-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmincostflow.cpp
110 lines (100 loc) · 2.45 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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
long long mincostflow(vector<vector<int>> E, vector<vector<long long>> cap, vector<vector<long long>> cost,
int s, int t, long long f)
{
int n = (int)E.size();
// reverse edge
vector<vector<int>> R(n);
for (int v=0; v<n; v++)
R[v].resize(E[v].size());
vector<vector<int>> E_ = E;
vector<vector<long long>> cap_ = cap;
vector<vector<long long>> cost_ = cost;
for (int v=0; v<n; v++)
for (int e=0; e<(int)E_[v].size(); e++)
{
int to = E_[v][e];
R[v][e] = (int)E[to].size();
E[to].push_back(v);
cap[to].push_back(0);
cost[to].push_back(-cost[v][e]);
R[to].push_back(e);
}
long long oo = 0xfff'ffff'ffff'ffffLL;
long long res = 0;
vector<long long> D(n);
vector<int> prevv(n);
vector<int> preve(n);
while (f>0)
{
// Bellman-Ford
for (long long &d: D)
d = oo;
D[s] = 0;
while (true)
{
bool up = false;
for (int v=0; v<n; v++)
if (D[v]<oo)
for (int e=0; e<(int)E[v].size(); e++)
{
int to = E[v][e];
if (cap[v][e]>0 && D[to]>D[v]+cost[v][e])
{
D[to] = D[v]+cost[v][e];
prevv[to] = v;
preve[to] = e;
up = true;
}
}
if (!up)
break;
}
if (D[t]==oo)
return oo;
long long d = f;
for (int v=t; v!=s; v=prevv[v])
d = min(d, cap[prevv[v]][preve[v]]);
f -= d;
res += d*D[t];
for (int v=t; v!=s; v=prevv[v])
{
cap[prevv[v]][preve[v]] -= d;
cap[v][R[prevv[v]][preve[v]]] += d;
}
}
return res;
}
#include <iostream>
int main()
{
vector<vector<int>> E
{
{1, 2},
{2, 3},
{4},
{2, 4},
{},
};
vector<vector<long long>> cap
{
{10, 2},
{6, 6},
{5},
{3, 8},
{}
};
vector<vector<long long>> cost
{
{2, 4},
{6, 2},
{2},
{3, 6},
{},
};
// 80
cout<<mincostflow(E, cap, cost, 0, 4, 9)<<endl;
}