結果

問題 No.2320 Game World for PvP
ユーザー lam6er
提出日時 2025-03-20 20:29:52
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 98 ms / 2,000 ms
コード長 4,225 bytes
コンパイル時間 165 ms
コンパイル使用メモリ 82,188 KB
実行使用メモリ 78,444 KB
最終ジャッジ日時 2025-03-20 20:30:41
合計ジャッジ時間 3,526 ms
ジャッジサーバーID
(参考情報)
judge3 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 30
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys
from collections import deque

class Edge:
    def __init__(self, to, rev, capacity):
        self.to = to
        self.rev = rev
        self.capacity = capacity

class Dinic:
    def __init__(self, n):
        self.size = n
        self.graph = [[] for _ in range(n)]
    
    def add_edge(self, fr, to, capacity):
        forward = Edge(to, len(self.graph[to]), capacity)
        backward = Edge(fr, len(self.graph[fr]), 0)
        self.graph[fr].append(forward)
        self.graph[to].append(backward)
    
    def bfs_level(self, s, t, level):
        q = deque()
        level[:] = [-1] * self.size
        level[s] = 0
        q.append(s)
        while q:
            v = q.popleft()
            for edge in self.graph[v]:
                if edge.capacity > 0 and level[edge.to] == -1:
                    level[edge.to] = level[v] + 1
                    q.append(edge.to)
                    if edge.to == t:
                        return
    
    def dfs_flow(self, v, t, flow, level, ptr):
        if v == t:
            return flow
        while ptr[v] < len(self.graph[v]):
            edge = self.graph[v][ptr[v]]
            if edge.capacity > 0 and level[v] < level[edge.to]:
                min_flow = min(flow, edge.capacity)
                result = self.dfs_flow(edge.to, t, min_flow, level, ptr)
                if result > 0:
                    edge.capacity -= result
                    self.graph[edge.to][edge.rev].capacity += result
                    return result
            ptr[v] += 1
        return 0
    
    def max_flow(self, s, t):
        flow = 0
        level = [-1] * self.size
        while True:
            self.bfs_level(s, t, level)
            if level[t] == -1:
                return flow
            ptr = [0] * self.size
            while True:
                f = self.dfs_flow(s, t, float('inf'), level, ptr)
                if f == 0:
                    break
                flow += f
            level = [-1] * self.size

def main():
    input = sys.stdin.read().split()
    idx = 0
    N = int(input[idx]); idx +=1
    S = int(input[idx]); idx +=1
    T = int(input[idx]); idx +=1
    
    E = list(map(int, input[idx:idx+S]))
    E = [x-1 for x in E]
    idx += S
    R = list(map(int, input[idx:idx+T]))
    R = [x-1 for x in R]
    idx += T
    
    C = []
    for _ in range(N):
        row = list(map(int, input[idx:idx+N]))
        idx += N
        C.append(row)
    
    E_set = set(E)
    R_set = set(R)
    for u in E_set:
        if u in R_set:
            print(0)
            return
    U = []
    for u in range(N):
        if u not in E_set and u not in R_set:
            U.append(u)
    
    # Compute fixed_sum
    fixed_sum = 0
    # sum pairs in E
    for i in range(len(E)):
        for j in range(i+1, len(E)):
            u = E[i]
            v = E[j]
            fixed_sum += C[u][v]
    for i in range(len(R)):
        for j in range(i+1, len(R)):
            u = R[i]
            v = R[j]
            fixed_sum += C[u][v]
    
    # For each undecided user, compute a_E and a_R
    a_E = []
    a_R = []
    for u in U:
        ae = 0
        for e in E:
            ae += C[u][e]
        ar = 0
        for r in R:
            ar += C[u][r]
        a_E.append(ae)
        a_R.append(ar)
    
    sum_a_plus_aR = sum( ae + ar for ae, ar in zip(a_E, a_R) )
    
    sum_undecided_C_all = 0
    M = len(U)
    for i in range(M):
        for j in range(i+1, M):
            u = U[i]
            v = U[j]
            sum_undecided_C_all += C[u][v]
    
    # Build Dinic's graph
    node_count = M + 2
    source = 0
    sink = M +1
    dinic = Dinic(node_count)
    
    for i in range(M):
        u_node = i +1
        dinic.add_edge(source, u_node, a_E[i])
        dinic.add_edge(u_node, sink, a_R[i])
    
    for i in range(M):
        u = U[i]
        u_node = i +1
        for j in range(M):
            if i == j:
                continue
            v = U[j]
            v_node = j +1
            dinic.add_edge(u_node, v_node, C[u][v])
    
    max_flow = dinic.max_flow(source, sink)
    
    total = fixed_sum + (sum_a_plus_aR + sum_undecided_C_all) - max_flow
    print(total)
    
if __name__ == '__main__':
    main()
0