結果
| 問題 | No.654 Air E869120 | 
| コンテスト | |
| ユーザー |  | 
| 提出日時 | 2020-09-24 00:26:58 | 
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) | 
| 結果 | 
                                AC
                                 
                             | 
| 実行時間 | 1,016 ms / 2,000 ms | 
| コード長 | 5,099 bytes | 
| コンパイル時間 | 276 ms | 
| コンパイル使用メモリ | 13,440 KB | 
| 実行使用メモリ | 184,832 KB | 
| 最終ジャッジ日時 | 2024-06-28 04:44:14 | 
| 合計ジャッジ時間 | 10,369 ms | 
| ジャッジサーバーID (参考情報) | judge2 / judge1 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 5 | 
| other | AC * 35 | 
ソースコード
import sys
import math
from collections import defaultdict
from collections import deque
sys.setrecursionlimit(1000000)
MOD = 10 ** 9 + 7
INF = 10 ** 20
input = lambda: sys.stdin.readline().strip()
NI = lambda: int(input())
NMI = lambda: map(int, input().split())
NLI = lambda: list(NMI())
SI = lambda: input()
class Dinic:
    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 = Dinic._edge(to, cap)
        e2 = Dinic._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):
        e1 = self.pos[i]
        e2 = e1.rev
        return Dinic.edge(e2.to, e1.to, e1.cap + e2.cap, e2.cap)
    def edges(self):
        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):
        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
    class _edge:
        def __init__(self, to, cap):
            self.to = to
            self.cap = cap
def compress(S):
    """ 座標圧縮 """
    zipped, unzipped = {}, {}
    for i, a in enumerate(sorted(S)):
        zipped[a] = i
        unzipped[i] = a
    return zipped, unzipped
def main():
    N, M, d = NMI()
    time_set = set()
    edges = []
    for i in range(M):
        u, v, p, q, w = NMI()
        u, v = u-1, v-1
        q = q + d
        time_set.add(p)
        time_set.add(q)
        edges.append([u, v, p, q, w])
    time_zip, time_unzip = compress(time_set)
    T = len(time_zip)
    din = Dinic(N*T)
    flight_times = [[] for _ in range(N)]
    for u, v, p, q, w in edges:
        p = time_zip[p]
        q = time_zip[q]
        din.add_edge(u*T+p, v*T+q, w)
        flight_times[u].append(p)
        flight_times[v].append(q)
    for n in range(N):
        flight_times[n].sort()
        f_len = len(flight_times[n])
        for f in range(f_len-1):
            p, q = flight_times[n][f], flight_times[n][f+1]
            din.add_edge(n*T+p, n*T+q, INF)
    if not flight_times[0] or not flight_times[-1]:
        print(0)
        exit()
    print(din.flow(0*T+flight_times[0][0], (N-1)*T+flight_times[N-1][-1]))
if __name__ == "__main__":
    main()
            
            
            
        