$\newcommand{\O}{\mathrm{O}}$
グラフ上の $s$ -> $t$ 間最大流を高速に求めるアルゴリズム. Dinitz と綴られることも多い.
時間計算量: $\O (n^2 m)$
class MaxFlow: class Edge: def __init__(self, to, cap, rev): self.to, self.cap, self.rev = to, cap, rev def __init__(self, node_size, inf): self._node = node_size self._inf = inf self._level = [-1]*self._node self._iter = [0]*self._node self._graph = [[] for _ in range(self._node)] def add_edge(self, from_, to, cap): self._graph[from_].append(self.Edge(to, cap, len(self._graph[to]))) self._graph[to].append(self.Edge(from_, 0, len(self._graph[from_])-1)) def bfs(self, start): self._level = [-1]*self._node que = deque() self._level[start] = 0 que.append(start) while que: cur_vertex = que.popleft() for e in self._graph[cur_vertex]: if e.cap > 0 > self._level[e.to]: self._level[e.to] = self._level[cur_vertex] + 1 que.append(e.to) def dfs(self, cur_vertex, end_vertex, flow): if cur_vertex == end_vertex: return flow while self._iter[cur_vertex] < len(self._graph[cur_vertex]): e = self._graph[cur_vertex][self._iter[cur_vertex]] if e.cap > 0 and self._level[cur_vertex] < self._level[e.to]: flowed = self.dfs(e.to, end_vertex, min(flow, e.cap)) if flowed > 0: e.cap -= flowed self._graph[e.to][e.rev].cap += flowed return flowed self._iter[cur_vertex] += 1 return 0 def solve(self, source, sink): flow = 0 while True: self.bfs(source) if self._level[sink] < 0: return flow self._iter = [0]*self._node while True: f = self.dfs(source, sink, self._inf) if f == 0: break flow += f
AOJ : Maximum Flow 提出コード