Skip to content

Commit 8e37cde

Browse files
committed
🥺chore
1 parent e03a2c5 commit 8e37cde

File tree

2 files changed

+126
-5
lines changed

2 files changed

+126
-5
lines changed

main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ def LR(n): return [L() for _ in range(n)]
1919
def IR(n): return [I() for _ in range(n)]
2020
def LIR(n): return [LI() for _ in range(n)]
2121
def LIR1(n): return [LI1() for _ in range(n)]
22-
def SR(n): return [SL() for _ in range(n)]
22+
def SLR(n): return [SL() for _ in range(n)]
2323
def LSR(n): return [LS() for _ in range(n)]
2424

2525
def perm(n, r): return math.factorial(n) // math.factorial(r)
2626
def comb(n, r): return math.factorial(n) // (math.factorial(r) * math.factorial(n-r))
2727

28-
def make_list(n, *args, default=0): return [make_list(*args, default=default) for _ in range(n)] if len(args) > 0 else [default for _ in range(n)]
28+
def make_list(n, *args, default=0): return [make_list(*args, default=default) for _ in range(n)] if args else [default for _ in range(n)]
2929

3030
dire = [[1, 0], [0, 1], [-1, 0], [0, -1]]
3131
dire8 = [[1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1], [1, -1]]

practice2/d/main.py

Lines changed: 124 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# thanks: https://atcoder.jp/contests/practice2/submissions/16784996
2+
13
#!usr/bin/env python3
24
from collections import defaultdict, deque, Counter, OrderedDict
35
from bisect import bisect_left, bisect_right
@@ -19,13 +21,13 @@ def LR(n): return [L() for _ in range(n)]
1921
def IR(n): return [I() for _ in range(n)]
2022
def LIR(n): return [LI() for _ in range(n)]
2123
def LIR1(n): return [LI1() for _ in range(n)]
22-
def SR(n): return [SL() for _ in range(n)]
24+
def SLR(n): return [SL() for _ in range(n)]
2325
def LSR(n): return [LS() for _ in range(n)]
2426

2527
def perm(n, r): return math.factorial(n) // math.factorial(r)
2628
def comb(n, r): return math.factorial(n) // (math.factorial(r) * math.factorial(n-r))
2729

28-
def make_list(n, *args, default=0): return [make_list(*args, default=default) for _ in range(n)] if len(args) > 0 else [default for _ in range(n)]
30+
def make_list(n, *args, default=0): return [make_list(*args, default=default) for _ in range(n)] if args else [default for _ in range(n)]
2931

3032
dire = [[1, 0], [0, 1], [-1, 0], [0, -1]]
3133
dire8 = [[1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1], [1, -1]]
@@ -36,8 +38,127 @@ def make_list(n, *args, default=0): return [make_list(*args, default=default) fo
3638

3739
sys.setrecursionlimit(1000000)
3840

41+
class MaxFlowGraph:
42+
def __init__(self, N):
43+
self.N = N
44+
self.graph = [[] for _ in range(N)]
45+
self.capacities = [dict() for _ in range(N)]
46+
47+
def add_edge(self, v, w, cap=1):
48+
self.graph[v].append(w)
49+
self.graph[w].append(v)
50+
self.capacities[v][w] = cap
51+
self.capacities[w][v] = 0
52+
53+
def bfs(self, s, t):
54+
self.level = [-1] * self.N
55+
q = deque([s])
56+
self.level[s] = 0
57+
while q:
58+
v = q.popleft()
59+
for w, cap in self.capacities[v].items():
60+
if cap and self.level[w] == -1:
61+
self.level[w] = self.level[v] + 1
62+
if w == t: return True
63+
q.append(w)
64+
return False
65+
66+
def dfs(self, s, t, limit):
67+
st = [t]
68+
while st:
69+
v = st[-1]
70+
if v == s: break
71+
#vから行ける全ての頂点について
72+
while self.it[v] < len(self.graph[v]):
73+
# w -> v の cap
74+
w = self.graph[v][self.it[v]]
75+
cap = self.capacities[w][v]
76+
if cap and self.level[w] != -1 and self.level[v] > self.level[w]:
77+
st.append(w)
78+
break
79+
self.it[v] += 1
80+
else:
81+
st.pop()
82+
self.level[v] = self.N
83+
else: return 0
84+
85+
flow = min(limit, min(self.capacities[st[i + 1]][st[i]] for i in range(len(st) - 2)))
86+
for i in range(len(st) - 1):
87+
self.capacities[st[i]][st[i+1]] += flow
88+
self.capacities[st[i+1]][st[i]] -= flow
89+
return flow
90+
91+
def flow(self, s, t, flow_limit=18446744073709551615):
92+
flow = 0
93+
while flow < flow_limit and self.bfs(s, t):
94+
self.it = [0]*self.N
95+
while flow < flow_limit:
96+
f = self.dfs(s, t, flow_limit - flow)
97+
if not f: break
98+
flow += f
99+
return flow
100+
101+
def min_cut(self, s):
102+
visited = [False]*self.N
103+
q = [s]
104+
while q:
105+
v = q.pop()
106+
visited[v] = True
107+
for w, cap in self.capacities[v].items():
108+
if cap and not visited[w]:
109+
q.append(w)
110+
39111
def main():
40-
N = I()
112+
N, M = LI()
113+
S = SLR(N)
114+
g = MaxFlowGraph(N*M+2)
115+
116+
s = N*M
117+
t = N*M+1
118+
119+
# 偶数はblack, 奇数はwhiteとして市松模様に塗る、二部グラフの最大マッチング問題
120+
# s -> black -> white -> t の辺を張って最大流を求める
121+
for y in range(N):
122+
for x in range(M):
123+
# black
124+
if (y+x) % 2 == 0:
125+
g.add_edge(s, M*y+x)
126+
for dy, dx in [[1, 0], [0, 1]]:
127+
ny, nx = y + dy, x + dx
128+
if 0 <= ny < N and 0 <= nx < M and S[y][x] == "." and S[ny][nx] == ".":
129+
g.add_edge(M*y+x, M*ny+nx)
130+
# white
131+
else:
132+
g.add_edge(M*y+x, t)
133+
for dy, dx in [[1, 0], [0, 1]]:
134+
ny, nx = y + dy, x + dx
135+
if 0 <= ny < N and 0 <= nx < M and S[y][x] == "." and S[ny][nx] == ".":
136+
g.add_edge(M*ny+nx, M*y+x)
137+
138+
print(g.flow(s, t))
139+
140+
# blackから考える
141+
for u in range(N*M+2):
142+
uy, ux = divmod(u, M)
143+
if (uy + ux) % 2 == 1: continue
144+
145+
for v, cap in g.capacities[u].items():
146+
if cap != 0: continue
147+
vy, vx = divmod(v, M)
148+
if u != s and u != t and v != s and v != t:
149+
if uy - 1 == vy:
150+
S[uy][ux], S[vy][vx] = "^", "v"
151+
elif uy + 1 == vy:
152+
S[uy][ux], S[vy][vx] = "v", "^"
153+
elif ux + 1 == vx:
154+
S[uy][ux], S[vy][vx] = ">", "<"
155+
elif ux - 1 == vx:
156+
S[uy][ux], S[vy][vx] = "<", ">"
157+
158+
for p in S:
159+
print("".join(p))
160+
161+
41162

42163
if __name__ == '__main__':
43164
main()

0 commit comments

Comments
 (0)