結果

問題 No.904 サメトロ
ユーザー NoneNone
提出日時 2021-04-01 22:27:47
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 99 ms / 1,000 ms
コード長 5,249 bytes
コンパイル時間 344 ms
コンパイル使用メモリ 81,904 KB
実行使用メモリ 76,496 KB
最終ジャッジ日時 2024-12-21 06:42:16
合計ジャッジ時間 3,741 ms
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 45 ms
53,408 KB
testcase_01 AC 46 ms
53,348 KB
testcase_02 AC 53 ms
61,072 KB
testcase_03 AC 67 ms
64,964 KB
testcase_04 AC 59 ms
62,208 KB
testcase_05 AC 45 ms
54,104 KB
testcase_06 AC 55 ms
61,624 KB
testcase_07 AC 63 ms
63,964 KB
testcase_08 AC 85 ms
73,704 KB
testcase_09 AC 44 ms
53,620 KB
testcase_10 AC 70 ms
68,120 KB
testcase_11 AC 80 ms
72,448 KB
testcase_12 AC 53 ms
59,036 KB
testcase_13 AC 46 ms
54,812 KB
testcase_14 AC 63 ms
64,496 KB
testcase_15 AC 54 ms
61,112 KB
testcase_16 AC 84 ms
74,320 KB
testcase_17 AC 44 ms
54,040 KB
testcase_18 AC 45 ms
53,452 KB
testcase_19 AC 49 ms
60,308 KB
testcase_20 AC 45 ms
53,620 KB
testcase_21 AC 70 ms
67,680 KB
testcase_22 AC 61 ms
64,028 KB
testcase_23 AC 63 ms
65,852 KB
testcase_24 AC 46 ms
53,276 KB
testcase_25 AC 43 ms
53,816 KB
testcase_26 AC 99 ms
76,496 KB
testcase_27 AC 64 ms
64,152 KB
testcase_28 AC 45 ms
53,420 KB
testcase_29 AC 54 ms
63,992 KB
testcase_30 AC 44 ms
54,480 KB
testcase_31 AC 44 ms
52,956 KB
testcase_32 AC 43 ms
53,816 KB
testcase_33 AC 42 ms
53,472 KB
testcase_34 AC 44 ms
53,428 KB
testcase_35 AC 43 ms
53,220 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

class MaxFlow:
    def __init__(self, n=0):
        self._n = n
        self.g = [[] for _ in range(n)]
        self.pos = []

    def add_edge(self, frm, to, cap):
        m = len(self.pos)
        e1 = MaxFlow._edge(to, cap)
        e2 = MaxFlow._edge(frm, 0)
        e1.rev = e2
        e2.rev = e1
        self.pos.append(e1)
        self.g[frm].append(e1)
        self.g[to].append(e2)
        return m

    class edge:
        def __init__(self, frm, to, cap, flow):
            self.frm = frm
            self.to = to
            self.cap = cap
            self.flow = flow

        def __iter__(self):
            yield self.frm
            yield self.to
            yield self.cap
            yield self.flow

    def get_edge(self, i):
        """ i 番目に追加された辺について (from, to, 初期の cap, 現在の流量(始めは 0)) """
        e1 = self.pos[i]
        e2 = e1.rev
        return MaxFlow.edge(e2.to, e1.to, e1.cap + e2.cap, e2.cap)

    def edges(self):
        """ get_edge の返り値をリストで並べたもの """
        return [self.get_edge(i) for i in range(len(self.pos))]

    def change_edge(self, i, new_cap, new_flow):
        e = self.pos[i]
        e.cap = new_cap - new_flow
        e.rev.cap = new_flow

    def flow(self, s, t, flow_limit=0XFFFFFFFFFFFFFFF):
        g = self.g
        flow = 0
        while flow < flow_limit:
            level = [-1] * self._n
            level[s] = 0
            que = [None] * self._n
            ql = 0
            qr = 1
            que[0] = s
            unreached = True
            while unreached and ql < qr:
                v = que[ql]
                ql += 1
                for e in g[v]:
                    to = e.to
                    if e.cap and level[to] < 0:
                        level[to] = level[v] + 1
                        if to == t:
                            unreached = False
                            break
                        que[qr] = to
                        qr += 1
            if unreached:
                return flow
            ptr = [len(es) for es in g]
            stack = []
            v = t
            up = flow_limit - flow
            res = 0
            while True:
                if v == s or not ptr[v]:
                    if v == s:
                        res = up
                    while stack:
                        tmp = res
                        e, up, res = stack.pop()
                        e.cap -= tmp
                        e.rev.cap += tmp
                        res += tmp
                        if res < up:
                            v = e.to
                            break
                    else:
                        flow += res
                        break
                i = ptr[v]
                while i:
                    i -= 1
                    e = g[v][i]
                    if level[e.to] == level[v] - 1 and e.rev.cap:
                        ptr[v] = i
                        stack.append((e.rev, up, res))
                        v = e.to
                        up = min(up, e.rev.cap)
                        res = 0
                        break
                else:
                    ptr[v] = i
        return flow

    def min_cut(self, s):
        """
        残余グラフから到達可能な頂点集合を返す。
        流量の最大値を十分大きくとった場合、この頂点集合はmin_cutとなる。
        """
        visited = [False] * self._n
        que = [None] * self._n
        ql = 0
        qr = 1
        que[0] = s
        visited[s] = True
        while ql < qr:
            p = que[ql]
            ql += 1
            for e in self.g[p]:
                if e.cap and not visited[e.to]:
                    visited[e.to] = True
                    que[qr] = e.to
                    qr += 1
        return visited

    def draw(self):
        """
        :return: グラフを可視化
        """
        import matplotlib.pyplot as plt
        import networkx as nx

        G = nx.DiGraph()

        for frm, to, cap, cap_now in self.edges():
            G.add_edge(frm, to, label="{}/{}".format(cap_now,cap))


        edge_labels = {(i, j): w['label'] for i, j, w in G.edges(data=True)}
        pos = nx.spring_layout(G)
        nx.draw_networkx(G, pos, with_labels=True, connectionstyle='arc3, rad = 0.1')
        nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
        plt.axis("off")
        plt.show()

    class _edge:
        def __init__(self, to, cap):
            self.to = to
            self.cap = cap

        def __iter__(self):
            yield self.to
            yield self.cap


def example():
    global input
    example = iter(
        """
7 6
0 1 4
1 3 1
1 4 1
2 5 1
3 6 1
4 6 1
        """
            .strip().split("\n"))

    input = lambda: next(example)

#####################################################################################
import sys
input = sys.stdin.readline

# example()

N=int(input())

mf = MaxFlow(2*N)
for i in range(1,N):
    a,b=map(int, input().split())
    for j in range(1,N):
        if i==j:continue
        mf.add_edge(i,N+j,a)
    mf.add_edge(0,i,a)
    mf.add_edge(N+i,N,b)

f=mf.flow(0,N)
print(f+1)
0