結果

問題 No.654 Air E869120
ユーザー tktk_snsntktk_snsn
提出日時 2020-09-24 23:19:11
言語 Python3
(3.12.2 + numpy 1.26.4 + scipy 1.12.0)
結果
AC  
実行時間 181 ms / 2,000 ms
コード長 3,916 bytes
コンパイル時間 111 ms
コンパイル使用メモリ 11,388 KB
実行使用メモリ 11,352 KB
最終ジャッジ日時 2023-09-10 14:09:24
合計ジャッジ時間 3,824 ms
ジャッジサーバーID
(参考情報)
judge15 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 21 ms
9,124 KB
testcase_01 AC 21 ms
9,080 KB
testcase_02 AC 21 ms
9,084 KB
testcase_03 AC 21 ms
9,000 KB
testcase_04 AC 21 ms
8,992 KB
testcase_05 AC 21 ms
8,980 KB
testcase_06 AC 22 ms
9,044 KB
testcase_07 AC 21 ms
8,936 KB
testcase_08 AC 21 ms
9,004 KB
testcase_09 AC 22 ms
9,080 KB
testcase_10 AC 95 ms
9,640 KB
testcase_11 AC 89 ms
9,516 KB
testcase_12 AC 89 ms
9,596 KB
testcase_13 AC 101 ms
9,596 KB
testcase_14 AC 91 ms
9,652 KB
testcase_15 AC 87 ms
9,432 KB
testcase_16 AC 167 ms
11,228 KB
testcase_17 AC 181 ms
11,184 KB
testcase_18 AC 149 ms
11,176 KB
testcase_19 AC 162 ms
11,140 KB
testcase_20 AC 61 ms
11,220 KB
testcase_21 AC 64 ms
11,352 KB
testcase_22 AC 40 ms
11,232 KB
testcase_23 AC 48 ms
11,144 KB
testcase_24 AC 65 ms
11,216 KB
testcase_25 AC 39 ms
11,220 KB
testcase_26 AC 44 ms
11,156 KB
testcase_27 AC 37 ms
10,960 KB
testcase_28 AC 42 ms
11,216 KB
testcase_29 AC 36 ms
11,068 KB
testcase_30 AC 35 ms
11,100 KB
testcase_31 AC 35 ms
11,140 KB
testcase_32 AC 36 ms
11,036 KB
testcase_33 AC 35 ms
11,060 KB
testcase_34 AC 35 ms
11,224 KB
testcase_35 AC 20 ms
9,100 KB
testcase_36 AC 20 ms
9,020 KB
testcase_37 AC 20 ms
9,012 KB
testcase_38 AC 20 ms
8,940 KB
testcase_39 AC 21 ms
9,096 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

from itertools import accumulate
from collections import deque
import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)


class MF_graph(object):
    def __init__(self, n):
        self.n = n
        self.g = [[] for _ in range(n)]  # to, rev, cap
        self.pos = []

    def add_edge(self, frm, to, cap):
        m = len(self.pos)
        self.pos.append((frm, len(self.g[frm])))
        self.g[frm].append([to, len(self.g[to]), cap])
        self.g[to].append([frm, len(self.g[frm]) - 1, 0])
        return m

    def get_edge(self, i):
        e_to, e_rev, e_cap = self.g[self.pos[i][0]][self.pos[i][1]]
        re_to, _, re_cap = self.g[e_to][e_rev]
        # from, to, cap, flow
        return (re_to, e_to, e_cap + re_cap, re_cap)

    def edges(self):
        m = len(self.pos)
        for i in range(m):
            yield self.get_edge(i)

    def change_edge(self, i, new_cap, new_flow):
        f, s = self.pos[i]
        rf, rs, _ = self.g[f][s]
        self.g[f][s][2] = new_cap - new_flow
        self.g[rf][rs][2] = new_flow
        return

    def dfs(self, s, v, up):
        if v == s:
            return up
        res = 0
        level_v = self.level[v]
        for i in range(self.iter[v], len(self.g[v])):
            u_to, u_rev, _ = self.g[v][i]
            if level_v <= self.level[u_to] or self.g[u_to][u_rev][2] == 0:
                continue
            d = self.dfs(s, u_to, min(up - res, self.g[u_to][u_rev][2]))
            if d <= 0:
                continue
            self.g[v][i][2] += d
            self.g[u_to][u_rev][2] -= d
            res += d
            if res == up:
                break
        return res

    def flow(self, s, t, flow_limit=10**18):
        self.iter = [0] * self.n

        flow = 0
        while flow < flow_limit:
            self.level = [-1] * self.n
            self.level[s] = 0
            que = deque([s])
            while que:
                v = que.popleft()
                for u_to, _, u_cap in self.g[v]:
                    if u_cap == 0 or self.level[u_to] >= 0:
                        continue
                    self.level[u_to] = self.level[v] + 1
                    if u_to == t:
                        break
                    que.append(u_to)

            if self.level[t] == -1:
                break
            self.iter = [0] * self.n
            while flow < flow_limit:
                f = self.dfs(s, t, flow_limit - flow)
                if not f:
                    break
                flow += f
        return flow

    def min_cut(self, s):
        visited = [False] * self.n
        que = deque([s])
        while que:
            v = que.popleft()
            visited[v] = True
            for u_to, _, u_cap in self.g[v]:
                if u_cap and (not visited[u_to]):
                    visited[u_to] = True
                    que.append(u_to)
        return visited


N, M, d = map(int, input().split())
U = 10**9
data = []

table = [set() for _ in range(N)]
table[0].add(0)
table[N - 1].add(10 ** 9)
for _ in range(M):
    s, t, p, q, w = map(int, input().split())
    s -= 1
    t -= 1
    table[s].add(p)
    table[t].add(q)
    table[t].add(q + d)
    data.append((s, t, p, q, w))

cnt = 0
ttoi = dict()
for airport, time in enumerate(table):
    time = sorted(time)
    for t in time:
        ttoi[(airport, t)] = cnt
        cnt += 1


g = MF_graph(cnt + 10)
source = cnt
sink = cnt + 1
inf = 10**20

g.add_edge(source, 0, inf)
goal = ttoi[(N-1, U)]
g.add_edge(goal, sink, inf)
for s, t, p, q, w in data:
    if t != N - 1:
        q += d
    x = ttoi[(s, p)]
    y = ttoi[(t, q)]
    g.add_edge(x, y, w)

for airport, time in enumerate(table):
    if len(time) < 2:
        continue
    time = sorted(time)
    for p, q in zip(time[:-1], time[1:]):
        x = ttoi[(airport, p)]
        y = ttoi[(airport, q)]
        g.add_edge(x, y, inf)


print(g.flow(source, sink))
0