結果

問題 No.1324 Approximate the Matrix
ユーザー tpynerivertpyneriver
提出日時 2020-12-21 11:29:34
言語 PyPy3
(7.3.15)
結果
MLE  
(最新)
AC  
(最初)
実行時間 -
コード長 2,514 bytes
コンパイル時間 269 ms
コンパイル使用メモリ 81,980 KB
実行使用メモリ 858,240 KB
最終ジャッジ日時 2024-09-21 12:48:41
合計ジャッジ時間 5,675 ms
ジャッジサーバーID
(参考情報)
judge1 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other MLE * 1
権限があれば一括ダウンロードができます

ソースコード

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

N, K = map(int, readline().split())
A = list(map(int, readline().split()))
B = list(map(int, readline().split()))

P = [list(map(int, readline().split())) for _ in range(N)]

st = N*N+2*N
en = st + 1
INF = 10**9+7
D = MinCostFlowwithDijkstra(en+1)

Ag = N*N
Bg = N*N+N
for i in range(N):
    D.add_edge(st, Ag+i, A[i], 0)
    D.add_edge(Bg+i, en, B[i], 0)

ans = 0
for i in range(N):
    for j in range(N):
        D.add_edge(Ag+i, N*i+j, A[i], 0)
        pij = P[i][j]
        ans += pij**2
        for k in range(200):
            D.add_edge(N*i+j, Bg+j, 1, INF + ((pij-k-1)**2 - (pij-k)**2))

print(ans + D.get_mf(st, en, K) - INF*K)
    
    
0