結果

問題 No.3539 Parentheses Square
コンテスト
ユーザー kidodesu
提出日時 2026-05-08 23:21:42
言語 PyPy3
(7.3.17)
コンパイル:
pypy3 -mpy_compile _filename_
実行:
pypy3 _filename_
結果
WA  
実行時間 -
コード長 6,098 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 174 ms
コンパイル使用メモリ 85,896 KB
実行使用メモリ 334,156 KB
最終ジャッジ日時 2026-05-08 23:22:10
合計ジャッジ時間 20,534 ms
ジャッジサーバーID
(参考情報)
judge2_0 / judge3_1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 39 WA * 2
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

class MFGraph:
    class Edge:
        def __init__(self, src, dst, cap, flow):
            self.src = src
            self.dst = dst
            self.cap = cap
            self.flow = flow

    class _Edge:
        def __init__(self, dst: int, cap: int) -> None:
            self.dst = dst
            self.cap = cap
            self.rev = None

    def __init__(self, n: int) -> None:
        self._n = n
        self._g = [[] for _ in range(n)]
        self._edges = []

    def add_edge(self, src: int, dst: int, cap: int) -> int:
        assert 0 <= src < self._n
        assert 0 <= dst < self._n
        assert 0 <= cap
        m = len(self._edges)
        e = MFGraph._Edge(dst, cap)
        re = MFGraph._Edge(src, 0)
        e.rev = re
        re.rev = e
        self._g[src].append(e)
        self._g[dst].append(re)
        self._edges.append(e)
        return m

    def get_edge(self, i: int) -> Edge:
        assert 0 <= i < len(self._edges)
        e = self._edges[i]
        re = e.rev
        return MFGraph.Edge(
            re.dst,
            e.dst,
            e.cap + re.cap,
            re.cap
        )

    def edges(self):
        return [self.get_edge(i) for i in range(len(self._edges))]

    def change_edge(self, i: int, new_cap: int, new_flow: int) -> None:
        assert 0 <= i < len(self._edges)
        assert 0 <= new_flow <= new_cap
        e = self._edges[i]
        e.cap = new_cap - new_flow
        assert e.rev is not None
        e.rev.cap = new_flow

    def flow(self, s: int, t: int, flow_limit = None) -> int:
        assert 0 <= s < self._n
        assert 0 <= t < self._n
        assert s != t
        if flow_limit is None:
            flow_limit = sum(e.cap for e in self._g[s])

        current_edge = [0] * self._n
        level = [0] * self._n

        def fill(arr, value: int) -> None:
            for i in range(len(arr)):
                arr[i] = value

        def bfs() -> bool:
            fill(level, self._n)
            queue = []
            q_front = 0
            queue.append(s)
            level[s] = 0
            while q_front < len(queue):
                v = queue[q_front]
                q_front += 1
                next_level = level[v] + 1
                for e in self._g[v]:
                    if e.cap == 0 or level[e.dst] <= next_level:
                        continue
                    level[e.dst] = next_level
                    if e.dst == t:
                        return True
                    queue.append(e.dst)
            return False

        def dfs(lim: int) -> int:
            stack = []
            edge_stack = []
            stack.append(t)
            while stack:
                v = stack[-1]
                if v == s:
                    flow = min(lim, min(e.cap for e in edge_stack))
                    for e in edge_stack:
                        e.cap -= flow
                        assert e.rev is not None
                        e.rev.cap += flow
                    return flow
                next_level = level[v] - 1
                while current_edge[v] < len(self._g[v]):
                    e = self._g[v][current_edge[v]]
                    re = e.rev
                    if level[e.dst] != next_level or re.cap == 0:
                        current_edge[v] += 1
                        continue
                    stack.append(e.dst)
                    edge_stack.append(re)
                    break
                else:
                    stack.pop()
                    if edge_stack:
                        edge_stack.pop()
                    level[v] = self._n
            return 0

        flow = 0
        while flow < flow_limit:
            if not bfs():
                break
            fill(current_edge, 0)
            while flow < flow_limit:
                f = dfs(flow_limit - flow)
                flow += f
                if f == 0:
                    break
        return flow

n = int(input())
N = n // 2 + 1
S = [input() for _ in range(n)]
E = {}
node = [[] for _ in range(n)]
for i in range(n):
    B = [[]]
    C = [[0 for _ in range(N)] for _ in range(N)]
    C[0][0] = 1
    for y in range(N):
        for x in range(y+1):
            if not C[y][x]:
                continue
            if y+1 < N and S[i][y+x] != ")":
                C[y+1][x] = 1
            if x+1 < N and S[i][y+x] != "(":
                C[y][x+1] = 1
    if not C[-1][-1]: exit(print(-1))
    C[-1][-1] = 2
    for y in range(N-1, -1, -1):
        for x in range(y, -1, -1):
            if C[y][x] != 2: continue
            if y and S[i][y+x-1] != ")" and C[y-1][x]:
                C[y-1][x] = 2
            if x and S[i][y+x-1] != "(" and C[y][x-1]:
                C[y][x-1] = 2
    for y in range(N):
        for x in range(N):
            if y < x:
                C[y][x] = 0
            if C[y][x] <= 1:
                C[y][x] = 0
    
    D = [[[] for _ in range(N)] for _ in range(N)]
    D[0][0].append("")
    for le in range(n):
        cnt = 200
        for y in range(le+1):
            x = le - y
            if not (0 <= y < N and 0 <= x < N): continue
            if not C[y][x]: continue
            for s in D[y][x]:
                if y+1 < N and S[i][y+x] != ")" and C[y+1][x] and cnt:
                    cnt -= 1
                    D[y+1][x].append(s+"(")
                if x+1 < N and S[i][y+x] != "(" and C[y][x+1] and cnt:
                    cnt -= 1
                    D[y][x+1].append(s+")")
    for d in D[-1][-1]:
        if not d in E:
            E[d] = len(E)
            ei = E[d]
        else:
            ei = E[d]
        node[i].append(ei)

Ei = [""] * len(E)
for d in E:
    Ei[E[d]] = d

mf = MFGraph(n+len(E)+2)
s = n+len(E)
t = s+1
for i in range(n):
    mf.add_edge(s, i, 1)
    for j in node[i]:
        mf.add_edge(i, n+j, 1)

for i in range(len(E)):
    mf.add_edge(n+i, t, 1)

ans = mf.flow(s, t, n)
if ans < n:
    print(-1)
else:
    Ans = ["" for _ in range(n)]
    for e in mf.edges():
        if e.flow == 1 and e.src < n:
            Ans[e.src] = Ei[e.dst-n]
    for ans in Ans:
        print(ans)
0