77#include < queue>
88#include < vector>
99
10+ #include " atcoder/internal_csr"
11+ #include " atcoder/internal_queue"
12+
1013namespace atcoder {
1114
1215template <class Cap , class Cost > struct mcf_graph {
1316 public:
1417 mcf_graph () {}
15- mcf_graph (int n) : _n(n), g(n) {}
18+ mcf_graph (int n) : _n(n) {}
1619
1720 int add_edge (int from, int to, Cap cap, Cost cost) {
1821 assert (0 <= from && from < _n);
1922 assert (0 <= to && to < _n);
2023 assert (0 <= cap);
2124 assert (0 <= cost);
22- int m = int (pos.size ());
23- pos.push_back ({from, int (g[from].size ())});
24- int from_id = int (g[from].size ());
25- int to_id = int (g[to].size ());
26- if (from == to) to_id++;
27- g[from].push_back (_edge{to, to_id, cap, cost});
28- g[to].push_back (_edge{from, from_id, 0 , -cost});
25+ int m = int (_edges.size ());
26+ _edges.push_back ({from, to, cap, 0 , cost});
2927 return m;
3028 }
3129
@@ -36,28 +34,17 @@ template <class Cap, class Cost> struct mcf_graph {
3634 };
3735
3836 edge get_edge (int i) {
39- int m = int (pos .size ());
37+ int m = int (_edges .size ());
4038 assert (0 <= i && i < m);
41- auto _e = g[pos[i].first ][pos[i].second ];
42- auto _re = g[_e.to ][_e.rev ];
43- return edge{
44- pos[i].first , _e.to , _e.cap + _re.cap , _re.cap , _e.cost ,
45- };
46- }
47- std::vector<edge> edges () {
48- int m = int (pos.size ());
49- std::vector<edge> result (m);
50- for (int i = 0 ; i < m; i++) {
51- result[i] = get_edge (i);
52- }
53- return result;
39+ return _edges[i];
5440 }
41+ std::vector<edge> edges () { return _edges; }
5542
5643 std::pair<Cap, Cost> flow (int s, int t) {
5744 return flow (s, t, std::numeric_limits<Cap>::max ());
5845 }
5946 std::pair<Cap, Cost> flow (int s, int t, Cap flow_limit) {
60- return slope (s, t, flow_limit).back ();
47+ return slope (s, t, flow_limit).back ();
6148 }
6249 std::vector<std::pair<Cap, Cost>> slope (int s, int t) {
6350 return slope (s, t, std::numeric_limits<Cap>::max ());
@@ -66,49 +53,122 @@ template <class Cap, class Cost> struct mcf_graph {
6653 assert (0 <= s && s < _n);
6754 assert (0 <= t && t < _n);
6855 assert (s != t);
56+
57+ int m = int (_edges.size ());
58+ std::vector<int > edge_idx (m);
59+
60+ auto g = [&]() {
61+ std::vector<int > degree (_n), redge_idx (m);
62+ std::vector<std::pair<int , _edge>> elist;
63+ elist.reserve (2 * m);
64+ for (int i = 0 ; i < m; i++) {
65+ auto e = _edges[i];
66+ edge_idx[i] = degree[e.from ]++;
67+ redge_idx[i] = degree[e.to ]++;
68+ elist.push_back ({e.from , {e.to , -1 , e.cap - e.flow , e.cost }});
69+ elist.push_back ({e.to , {e.from , -1 , e.flow , -e.cost }});
70+ }
71+ auto _g = internal::csr<_edge>(_n, elist);
72+ for (int i = 0 ; i < m; i++) {
73+ auto e = _edges[i];
74+ edge_idx[i] += _g.start [e.from ];
75+ redge_idx[i] += _g.start [e.to ];
76+ _g.elist [edge_idx[i]].rev = redge_idx[i];
77+ _g.elist [redge_idx[i]].rev = edge_idx[i];
78+ }
79+ return _g;
80+ }();
81+
82+ auto result = slope (g, s, t, flow_limit);
83+
84+ for (int i = 0 ; i < m; i++) {
85+ auto e = g.elist [edge_idx[i]];
86+ _edges[i].flow = _edges[i].cap - e.cap ;
87+ }
88+
89+ return result;
90+ }
91+
92+ private:
93+ int _n;
94+ std::vector<edge> _edges;
95+
96+ // inside edge
97+ struct _edge {
98+ int to, rev;
99+ Cap cap;
100+ Cost cost;
101+ };
102+
103+ std::vector<std::pair<Cap, Cost>> slope (internal::csr<_edge>& g,
104+ int s,
105+ int t,
106+ Cap flow_limit) {
69107 // variants (C = maxcost):
70108 // -(n-1)C <= dual[s] <= dual[i] <= dual[t] = 0
71109 // reduced cost (= e.cost + dual[e.from] - dual[e.to]) >= 0 for all edge
72- std::vector<Cost> dual (_n, 0 ), dist (_n);
73- std::vector<int > pv (_n), pe (_n);
110+
111+ // dual_dist[i] = (dual[i], dist[i])
112+ std::vector<std::pair<Cost, Cost>> dual_dist (_n);
113+ std::vector<int > prev_e (_n);
74114 std::vector<bool > vis (_n);
75115 struct Q {
76116 Cost key;
77117 int to;
78118 bool operator <(Q r) const { return key > r.key ; }
79119 };
120+ std::vector<int > que_min;
80121 std::vector<Q> que;
81122 auto dual_ref = [&]() {
82- std::fill (dist.begin (), dist.end (),
83- std::numeric_limits<Cost>::max ());
123+ for (int i = 0 ; i < _n; i++) {
124+ dual_dist[i].second = std::numeric_limits<Cost>::max ();
125+ }
84126 std::fill (vis.begin (), vis.end (), false );
127+ que_min.clear ();
85128 que.clear ();
86129
87- dist[s] = 0 ;
88- que.push_back (Q{0 , s});
89- std::push_heap (que.begin (), que.end ());
90- while (!que.empty ()) {
91- int v = que.front ().to ;
92- std::pop_heap (que.begin (), que.end ());
93- que.pop_back ();
130+ // que[0..heap_r) was heapified
131+ size_t heap_r = 0 ;
132+
133+ dual_dist[s].second = 0 ;
134+ que_min.push_back (s);
135+ while (!que_min.empty () || !que.empty ()) {
136+ int v;
137+ if (!que_min.empty ()) {
138+ v = que_min.back ();
139+ que_min.pop_back ();
140+ } else {
141+ while (heap_r < que.size ()) {
142+ heap_r++;
143+ std::push_heap (que.begin (), que.begin () + heap_r);
144+ }
145+ v = que.front ().to ;
146+ std::pop_heap (que.begin (), que.end ());
147+ que.pop_back ();
148+ heap_r--;
149+ }
94150 if (vis[v]) continue ;
95151 vis[v] = true ;
96152 if (v == t) break ;
97153 // dist[v] = shortest(s, v) + dual[s] - dual[v]
98154 // dist[v] >= 0 (all reduced cost are positive)
99155 // dist[v] <= (n-1)C
100- for (int i = 0 ; i < int (g[v].size ()); i++) {
101- auto e = g[v][i];
102- if (vis[e.to ] || !e.cap ) continue ;
156+ Cost dual_v = dual_dist[v].first , dist_v = dual_dist[v].second ;
157+ for (int i = g.start [v]; i < g.start [v + 1 ]; i++) {
158+ auto e = g.elist [i];
159+ if (!e.cap ) continue ;
103160 // |-dual[e.to] + dual[v]| <= (n-1)C
104161 // cost <= C - -(n-1)C + 0 = nC
105- Cost cost = e.cost - dual[e.to ] + dual[v];
106- if (dist[e.to ] - dist[v] > cost) {
107- dist[e.to ] = dist[v] + cost;
108- pv[e.to ] = v;
109- pe[e.to ] = i;
110- que.push_back (Q{dist[e.to ], e.to });
111- std::push_heap (que.begin (), que.end ());
162+ Cost cost = e.cost - dual_dist[e.to ].first + dual_v;
163+ if (dual_dist[e.to ].second - dist_v > cost) {
164+ Cost dist_to = dist_v + cost;
165+ dual_dist[e.to ].second = dist_to;
166+ prev_e[e.to ] = e.rev ;
167+ if (dist_to == dist_v) {
168+ que_min.push_back (e.to );
169+ } else {
170+ que.push_back (Q{dist_to, e.to });
171+ }
112172 }
113173 }
114174 }
@@ -119,29 +179,29 @@ template <class Cap, class Cost> struct mcf_graph {
119179 for (int v = 0 ; v < _n; v++) {
120180 if (!vis[v]) continue ;
121181 // dual[v] = dual[v] - dist[t] + dist[v]
122- // = dual[v] - (shortest(s, t) + dual[s] - dual[t]) + (shortest(s, v) + dual[s] - dual[v])
123- // = - shortest(s, t) + dual[t] + shortest(s, v)
124- // = shortest(s, v) - shortest(s, t) >= 0 - (n-1)C
125- dual[v] -= dist[t] - dist[v];
182+ // = dual[v] - (shortest(s, t) + dual[s] - dual[t]) +
183+ // (shortest(s, v) + dual[s] - dual[v]) = - shortest(s,
184+ // t) + dual[t] + shortest(s, v) = shortest(s, v) -
185+ // shortest(s, t) >= 0 - (n-1)C
186+ dual_dist[v].first -= dual_dist[t].second - dual_dist[v].second ;
126187 }
127188 return true ;
128189 };
129190 Cap flow = 0 ;
130191 Cost cost = 0 , prev_cost_per_flow = -1 ;
131- std::vector<std::pair<Cap, Cost>> result;
132- result.push_back ({flow, cost});
192+ std::vector<std::pair<Cap, Cost>> result = {{Cap (0 ), Cost (0 )}};
133193 while (flow < flow_limit) {
134194 if (!dual_ref ()) break ;
135195 Cap c = flow_limit - flow;
136- for (int v = t; v != s; v = pv[v] ) {
137- c = std::min (c, g[pv[v]][pe[v] ].cap );
196+ for (int v = t; v != s; v = g. elist [prev_e[v]]. to ) {
197+ c = std::min (c, g. elist [g. elist [prev_e[v]]. rev ].cap );
138198 }
139- for (int v = t; v != s; v = pv[v] ) {
140- auto & e = g[pv[v]][pe [v]];
141- e.cap - = c;
142- g[v][ e.rev ].cap + = c;
199+ for (int v = t; v != s; v = g. elist [prev_e[v]]. to ) {
200+ auto & e = g. elist [prev_e [v]];
201+ e.cap + = c;
202+ g. elist [ e.rev ].cap - = c;
143203 }
144- Cost d = -dual [s];
204+ Cost d = -dual_dist [s]. first ;
145205 flow += c;
146206 cost += c * d;
147207 if (prev_cost_per_flow == d) {
@@ -152,18 +212,6 @@ template <class Cap, class Cost> struct mcf_graph {
152212 }
153213 return result;
154214 }
155-
156- private:
157- int _n;
158-
159- struct _edge {
160- int to, rev;
161- Cap cap;
162- Cost cost;
163- };
164-
165- std::vector<std::pair<int , int >> pos;
166- std::vector<std::vector<_edge>> g;
167215};
168216
169217} // namespace atcoder
0 commit comments