結果

問題 No.1341 真ん中を入れ替えて門松列
ユーザー tpynerivertpyneriver
提出日時 2021-01-16 15:17:28
言語 PyPy3
(7.3.15)
結果
TLE  
実行時間 -
コード長 3,469 bytes
コンパイル時間 479 ms
コンパイル使用メモリ 87,128 KB
実行使用メモリ 264,044 KB
最終ジャッジ日時 2023-08-18 12:40:23
合計ジャッジ時間 5,582 ms
ジャッジサーバーID
(参考情報)
judge11 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 125 ms
82,252 KB
testcase_01 AC 78 ms
71,384 KB
testcase_02 AC 80 ms
71,340 KB
testcase_03 AC 80 ms
71,496 KB
testcase_04 AC 80 ms
71,408 KB
testcase_05 AC 80 ms
71,448 KB
testcase_06 AC 313 ms
79,848 KB
testcase_07 TLE -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys
readline = sys.stdin.readline
from heapq import heappop as hpp, heappush as hp
class MinCostFlowwithDijkstra:
    INF = 1<<60
    
    def __init__(self, N):
        self.N = N
        self.Edge = [[] for _ in range(N)]
    
    def add_edge(self, st, en, cap, cost):
        self.Edge[st].append([en, cap, cost, len(self.Edge[en])])
        self.Edge[en].append([st, 0, -cost, len(self.Edge[st])-1])
    
    def get_mf(self, so, si, fl):
        N = self.N
        INF = self.INF
        res = 0
        Pot = [0]*N
        geta = N
        
        
        prv = [None]*N
        prenum = [None]*N
        while fl:
            dist = [INF]*N
            dist[so] = 0
            Q = [so]
            
            while Q:
                cost, vn = divmod(hpp(Q), geta)
                if dist[vn] < cost:
                    continue
                
                for enum in range(len(self.Edge[vn])):
                    vf, cap, cost, _ = self.Edge[vn][enum]
                    cc = dist[vn] + cost - Pot[vn] + Pot[vf]
                    if cap > 0 and dist[vf] > cc:
                        dist[vf] = cc
                        prv[vf] = vn
                        prenum[vf] = enum
                        hp(Q, cc*geta + vf)
            
            if dist[si] == INF:
                return -1
            
            for i in range(N):
                Pot[i] -= dist[i]
            
            cfl = fl
            vf = si
            while vf != so:
                cfl = min(cfl, self.Edge[prv[vf]][prenum[vf]][1])
                vf = prv[vf]
            
            fl -= cfl
            res -= cfl*Pot[si]
            vf = si
            while vf != so:
                e = self.Edge[prv[vf]][prenum[vf]]
                e[1] -= cfl
                self.Edge[vf][e[3]][1] += cfl
                vf = prv[vf]
        return res
    
    

INF = 1<<60  
N, M = map(int, readline().split())

ABC = [list(map(int, readline().split())) for _ in range(N)]
Ai = [None]*N
Ci = [None]*N
B = [None]*N
for i in range(N):
    a, b, c = ABC[i]
    B[i] = b
    if a > c:
        a, c = c, a
    Ai[i] = (a, i)
    Ci[i] = (c, i)


Ai.sort()
Ci.sort()
g = N
g2 = N+N
g3 = N+N+N
st = g3 + N
en = st+1


geta = 10**9+7
T = MinCostFlowwithDijkstra(en+1)
for i in range(N):
    b = B[i]
    
    ok = N
    ng = -1
    while abs(ok-ng) > 1:
        med = (ok+ng)//2
        if b < Ai[med][0]:
            ok = med
        else:
            ng = med
    if ok != N:
        aidx = Ai[ok][1]
        T.add_edge(i, g+aidx, 1, geta)
        #print(f'aidx:{aidx} ai:{Ai[aidx][1]} i:{i} bi:{B[i]}')
    
    ok = -1
    ng = N
    while abs(ok-ng) > 1:
        med = (ok+ng)//2
        if b > Ci[med][0]:
            ok = med
        else:
            ng = med
    if ok != -1:
        cidx = Ci[ok][1]
        T.add_edge(i, g2+cidx, 1, geta-b)
        #print(f'cidx:{cidx} ci:{Ci[cidx][1]} i:{i} bi:{B[i]}')
    
    _, ai = Ai[i]
    c, ci = Ci[i]
    T.add_edge(st, i, 1, 0)
    T.add_edge(g+ai, g3+ai, 1, geta-c)
    T.add_edge(g2+ci, g3+ci, 1, geta)
    T.add_edge(g3+i, en, 1, 0)

for i in range(N-1):
    _, ap = Ai[i]
    _, an = Ai[i+1]
    _, cp = Ci[i]
    _, cn = Ci[i+1]
    T.add_edge(g+ap, g+an, INF, 0)
    T.add_edge(g2+cn, g2+cp, INF, 0)


mf = T.get_mf(st, en, N)
if mf == -1:
    print('NO')
else:
    print('YES')
    mf = 2*N*geta - mf
    #print(mf)
    if mf >= M:
        print('KADOMATSU!')
    else:
        print('NO')
    

0