-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathA.cpp
112 lines (87 loc) · 2.82 KB
/
A.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
111
112
#include <iostream>
#include <climits>
#include <vector>
#include <deque>
size_t n, m;
const long long INF = LONG_LONG_MAX;
struct Edge {
int from, to;
long long flow, cap, cost;
int reversed = -1;
Edge(int from, int to, long long int f, long long int cap, long long int cost) : from(from), to(to), flow(f),
cap(cap),
cost(cost) {}
};
std::vector<std::vector<Edge>> edges;
std::vector<long long> d;
std::vector<int> id;
std::vector<Edge*> p;
void addEdge(int from, int to, long long flow, long long cap, long long cost) {
Edge edge = Edge(from, to, flow, cap, cost);
Edge rev = Edge(to, from, flow, 0, -cost);
edges[from].push_back(edge);
edges[to].push_back(rev);
edges[from].back().reversed = edges[to].size() - 1;
edges[to].back().reversed = edges[from].size() - 1;
}
long long levitAlgorithm() {
long long minCost = 0;
long long maxFlow = 0;
while (true) {
std::deque<int> q;
id.assign(n + 1, 0);
d.assign(n + 1, INF);
p.resize(n + 1);
d[1] = 0;
q.push_back(1);
while (!q.empty()) {
int u = q.front();
q.pop_front();
id[u] = 2;
for (Edge& edge : edges[u]) {
if (edge.flow < edge.cap && d[edge.to] > d[edge.from] + edge.cost) {
d[edge.to] = d[edge.from] + edge.cost;
if (!id[edge.to]) {
q.push_back(edge.to);
} else if (id[edge.to] == 2) {
q.push_front(edge.to);
}
id[edge.to] = 1;
p[edge.to] = &edge;
}
}
}
long long del = INF;
if (d[n] == INF) {
break;
} else {
for (int u = n; u != 1; u = p[u]->from) {
Edge* edge = p[u];
del = std::min(del, edge->cap - edge->flow);
}
for (int u = n; u != 1; u = p[u]->from) {
Edge* edge = p[u];
Edge* reversed = &edges[edge->to][edge->reversed];
edge->flow += del;
reversed->flow -= del;
minCost += del * edge->cost;
}
maxFlow += del;
}
}
return minCost;
}
int main() {
freopen("mincost.in", "r", stdin);
freopen("mincost.out", "w", stdout);
std::cin >> n >> m;
edges.assign(n + 1, std::vector<Edge>());
for (int i = 0; i < m; ++i) {
int from, to;
long long cap, cost;
std::cin >> from >> to >> cap >> cost;
addEdge(from, to, 0, cap, cost);
}
std::cout << levitAlgorithm();
return 0;
}