結果
問題 | No.2328 Build Walls |
ユーザー |
![]() |
提出日時 | 2025-03-31 17:36:25 |
言語 | PyPy3 (7.3.15) |
結果 |
MLE
|
実行時間 | - |
コード長 | 4,774 bytes |
コンパイル時間 | 329 ms |
コンパイル使用メモリ | 82,584 KB |
実行使用メモリ | 640,868 KB |
最終ジャッジ日時 | 2025-03-31 17:36:56 |
合計ジャッジ時間 | 6,055 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 10 MLE * 1 -- * 23 |
ソースコード
import sysfrom collections import dequeclass Edge:def __init__(self, to, rev, capacity):self.to = toself.rev = revself.capacity = capacityclass Dinic:def __init__(self, n):self.size = nself.graph = [[] for _ in range(n)]def add_edge(self, fr, to, cap):forward = Edge(to, len(self.graph[to]), cap)backward = Edge(fr, len(self.graph[fr]), 0)self.graph[fr].append(forward)self.graph[to].append(backward)def bfs_level(self, s, t, level):q = deque()level[:] = [-1] * self.sizelevel[s] = 0q.append(s)while q:v = q.popleft()for edge in self.graph[v]:if edge.capacity > 0 and level[edge.to] == -1:level[edge.to] = level[v] + 1q.append(edge.to)if edge.to == t:returndef dfs_flow(self, v, t, flow, level, ptr):if v == t:return flowwhile ptr[v] < len(self.graph[v]):edge = self.graph[v][ptr[v]]if edge.capacity > 0 and level[v] < level[edge.to]:pushed = self.dfs_flow(edge.to, t, min(flow, edge.capacity), level, ptr)if pushed > 0:edge.capacity -= pushedself.graph[edge.to][edge.rev].capacity += pushedreturn pushedptr[v] += 1return 0def max_flow(self, s, t):flow = 0level = [-1] * self.sizewhile True:self.bfs_level(s, t, level)if level[t] == -1:return flowptr = [0] * self.sizepushed = self.dfs_flow(s, t, float('inf'), level, ptr)while pushed > 0:flow += pushedpushed = self.dfs_flow(s, t, float('inf'), level, ptr)level = [-1] * self.sizeclass NodeAssigner:def __init__(self, H, W):self.H = Hself.W = Wself.node_count = 2 # S=0, T=1self.in_node = {}self.out_node = {}# Row 1for j in range(1, W + 1):node = self.node_countself.in_node[(1, j)] = nodeself.out_node[(1, j)] = nodeself.node_count += 1# Rows 2 to H-1for i in range(2, H):for j in range(1, W + 1):in_node = self.node_countself.node_count += 1out_node = self.node_countself.node_count += 1self.in_node[(i, j)] = in_nodeself.out_node[(i, j)] = out_node# Row Hfor j in range(1, W + 1):node = self.node_countself.in_node[(H, j)] = nodeself.out_node[(H, j)] = nodeself.node_count += 1def get_in_node(self, i, j):return self.in_node[(i, j)]def get_out_node(self, i, j):return self.out_node[(i, j)]def main():H, W = map(int, sys.stdin.readline().split())A_rows = H - 2A = []for _ in range(H - 2):A.append(list(map(int, sys.stdin.readline().split())))INF = 1 << 60assigner = NodeAssigner(H, W)dinic = Dinic(assigner.node_count)# Add edges for split nodes (in -> out)for i in range(2, H):for j in range(1, W + 1):# row in A is i-2 (since A is rows 2 to H-1)a = A[i - 2][j - 1]in_node = assigner.get_in_node(i, j)out_node = assigner.get_out_node(i, j)if a == -1:capacity = INFelse:capacity = adinic.add_edge(in_node, out_node, capacity)directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]for i in range(1, H + 1):for j in range(1, W + 1):for di, dj in directions:ni, nj = i + di, j + djif 1 <= ni <= H and 1 <= nj <= W:from_out = assigner.get_out_node(i, j)to_in = assigner.get_in_node(ni, nj)dinic.add_edge(from_out, to_in, INF)# Reverse edge is automatically added with 0 capacity# Connect S to first rowfor j in range(1, W + 1):in_node = assigner.get_in_node(1, j)dinic.add_edge(0, in_node, INF)# Connect last row to Tfor j in range(1, W + 1):out_node = assigner.get_out_node(H, j)dinic.add_edge(out_node, 1, INF)max_flow = dinic.max_flow(0, 1)if max_flow >= INF:print(-1)else:print(max_flow)if __name__ == '__main__':main()