@@ -141,8 +141,9 @@ def preflow():
141
141
edge .flow = edge .capacity
142
142
excess [edge .end ] += edge .flow
143
143
144
- active .append (edge .end )
145
- in_queue [edge .end ] = True
144
+ if edge .end != target :
145
+ active .append (edge .end )
146
+ in_queue [edge .end ] = True
146
147
147
148
edges .append (edge )
148
149
return edges , excess , label , source
@@ -189,165 +190,3 @@ def relabel(node: int):
189
190
if u not in (source , target ) and excess [u ] > 0 :
190
191
active .append (u )
191
192
in_queue [u ] = True
192
-
193
-
194
- """
195
- class MaxFlow(ABC):
196
-
197
- def __init__(self, graph: Graph, source: int, target: int):
198
- self.graph = graph
199
- self.source = source
200
- self.target = target
201
-
202
- @abstractmethod
203
- def step(self):
204
- pass
205
-
206
-
207
- class FordFulkerson(MaxFlow):
208
-
209
- def __init__(self, graph: Graph, source: int, target: int, path_algo=dfs):
210
- super().__init__(graph, source, target)
211
- self.path_algo = path_algo
212
-
213
- def step(self):
214
- if result := self.path_algo(self.graph, self.source, self.target):
215
- parent, *_ = result
216
- path_flow = math.inf
217
-
218
- tmp = self.target
219
- path = deque()
220
- while tmp != self.source:
221
- path_flow = min(path_flow, parent[tmp].residual_capacity())
222
- path.appendleft(parent[tmp])
223
- tmp = parent[tmp].start
224
-
225
- tmp = self.target
226
- while tmp != self.source:
227
- parent[tmp].adjust(path_flow)
228
- tmp = parent[tmp].start
229
-
230
- return list(path)
231
-
232
-
233
- class EdmondsKarp(FordFulkerson):
234
-
235
- def __init__(self, graph: Graph, source: int, target: int):
236
- super().__init__(graph, source, target, bfs)
237
-
238
-
239
- class CapacityScaling(MaxFlow):
240
-
241
- def __init__(self, graph: Graph, source: int, target: int):
242
- super().__init__(graph, source, target)
243
- max_capacity = max(e.capacity for e in graph.get_edges())
244
- self.delta = 2 ** math.floor(math.log(max_capacity, 2))
245
-
246
- def step(self):
247
- if result := bfs_capacity(self.graph, self.source, self.target, self.delta):
248
- parent, *_ = result
249
- path_flow = math.inf
250
-
251
- tmp = self.target
252
- path = deque()
253
- while tmp != self.source:
254
- path_flow = min(path_flow, parent[tmp].residual_capacity())
255
- path.appendleft(parent[tmp])
256
- tmp = parent[tmp].start
257
-
258
- tmp = self.target
259
- while tmp != self.source:
260
- parent[tmp].adjust(path_flow)
261
- tmp = parent[tmp].start
262
-
263
- return list(path)
264
- else:
265
- if self.delta > 1:
266
- self.delta /= 2
267
- return self.step()
268
-
269
-
270
- class Dinic(MaxFlow):
271
-
272
- def __init__(self, graph: Graph, source: int, target: int):
273
- super().__init__(graph, source, target)
274
-
275
- def step(self):
276
- if result := bfs(self.graph, self.source, self.target):
277
- _, level = result
278
- start = [0] * (self.graph.number_of_nodes() + 1)
279
- edges = []
280
- while flow := self.blocking_flow(self.source, math.inf, start, level, edges):
281
- pass
282
- return edges, level
283
-
284
- def blocking_flow(self, u: int, flow: int, start: list[int], level: list[int], edges: list):
285
- # dfs in acyclic layer graph
286
-
287
- if u == self.target:
288
- return flow
289
-
290
- while start[u] < self.graph.get_degree(u):
291
- edge = self.graph.get_edges_by_node(u)[start[u]] # edge.start == u
292
- if level[edge.end] == level[edge.start] + 1 and edge.residual_capacity() > 0:
293
- curr_flow = min(flow, edge.residual_capacity())
294
- curr_flow = self.blocking_flow(edge.end, curr_flow, start, level, edges)
295
-
296
- if curr_flow and curr_flow > 0:
297
- edge.adjust(curr_flow)
298
- edges.append(edge)
299
- return curr_flow
300
- start[u] += 1
301
-
302
-
303
- class GoldbergTarjan(MaxFlow): # TODO
304
-
305
- def __init__(self, graph: Graph, source: int, target: int):
306
- super().__init__(graph, source, target)
307
- self.excess = [0] * graph.number_of_nodes()
308
- self.label = [0] * graph.number_of_nodes()
309
- self.active = deque()
310
- self.preflow_executed = False
311
-
312
- def preflow(self):
313
- self.preflow_executed = True
314
- self.label[self.source] = self.graph.number_of_nodes()
315
- for edge in self.graph.get_edges_by_node(self.source):
316
- if not edge.reverse_edge:
317
- edge.flow = edge.capacity
318
- self.excess[edge.end] += edge.flow
319
- self.active.append(edge.end)
320
-
321
- def push(self, u):
322
- for edge in self.graph.get_edges_by_node(u):
323
- if edge.reverse_edge:
324
- continue
325
- if edge.flow == edge.capacity:
326
- continue
327
-
328
- v = edge.end
329
- if self.label[u] > self.label[v]:
330
- flow = min(edge.residual_capacity(), self.excess[u])
331
- self.excess[u] -= flow
332
- self.excess[v] += flow
333
- edge.adjust(flow)
334
-
335
- def relabel(self, u):
336
- self.label[u] = 1 + min(self.label[edge.v]
337
- for edge in self.graph.get_edges_by_node(u)
338
- if edge.residual_capacity() > 0)
339
-
340
- def step(self):
341
- if not self.preflow_executed:
342
- return self.preflow()
343
-
344
- if self.active:
345
- u = self.active.popleft()
346
- if any(self.excess[edge.end] > 0 for edge in self.graph.get_edges_by_node(u)):
347
- return self.push(u)
348
- else:
349
- return self.relabel(u)
350
-
351
- if u not in (s, t) and self.excess[u] > 0:
352
- self.active.append(u)
353
- """
0 commit comments