maxflow - shakayami/ACL-for-python GitHub Wiki
maxflow
最大フロー問題を解きます。 冒頭の
from collections import deque
が無いとエラーになります。
初期化
G=mf_graph(K)
Kはグラフの頂点数です。 初期化した直後は、頂点数Kで辺0のグラフとなります。
辺の追加
G.add_edge(u,v,c)
uからvへ、最大容量c,流量0の辺を追加します。
flow
ans=G.flow(s,t)
sからtへの最大フローを求めます。
edges
for e in G.edges():
if e["flow"]==0:
continue
print(e)
flowを実行した後には、どの辺にどれだけの流量が流れているかを示す値が残ります。
最大フローを求めた後、実際に最大となる状況を構成することが出来ます。
edgesはリストの形になっていて、リストの各要素はdictの構造を持っています。 そのdictにおいては、from,to,cap,flowという要素を持っています。これは、
- from->toという辺を持っている。
- 最大流量capの辺にflowだけ辺が流れている
という意味となっています。
min_cut
最小カットが求められます。
G.min_cut(s)
長さKのlistが返ってきます。
使用例
(https://atcoder.jp/contests/practice2/tasks/practice2_d)
from collections import deque
class mf_graph:
# (中略)
N,M=map(int,input().split())
S=[list(input()) for i in range(N)]
G=mf_graph(N*M+2)
for i in range(N):
for j in range(M):
if S[i][j]=="#":continue
v=i*M+j
if (i+j)%2==0:
G.add_edge(N*M,v,1)
else:
G.add_edge(v,N*M+1,1)
for i in range(N):
for j in range(M):
if (i+j)%2 or S[i][j]=="#":continue
v0=i*M+j
if i>0 and S[i-1][j]==".":
v1=(i-1)*M+j
G.add_edge(v0,v1,1)
if j>0 and S[i][j-1]==".":
v1=i*M+(j-1)
G.add_edge(v0,v1,1)
if i+1<N and S[i+1][j]==".":
v1=(i+1)*M+j
G.add_edge(v0,v1,1)
if j+1<M and S[i][j+1]==".":
v1=i*M+(j+1)
G.add_edge(v0,v1,1)
print(G.flow(N*M,N*M+1))
T=[[S[i][j] for j in range(M)] for i in range(N)]
for e in G.edges():
if e["from"]==N*M or e["to"]==N*M+1 or e["flow"]==0:
continue
i0=e["from"]//M
j0=e["from"]%M
i1=e["to"]//M
j1=e["to"]%M
if i0==i1+1:
T[i1][j1]="v"
T[i0][j0]="^"
elif j0==j1+1:
T[i1][j1]=">";T[i0][j0]="<"
elif i0==i1-1:
T[i0][j0]="v"
T[i1][j1]="^"
else:
T[i0][j0]=">";T[i1][j1]="<"
for i in range(N):
print("".join(T[i]))
トラブルシューティング
もしREになった場合、原因として再帰上限に引っかかったということが考えられる。そのような場合においては、
import sys
sys.setrecursionlimit(hoge)
といったコードを先頭に加えるとよい。詳しくはここを参照