結果
問題 |
No.1341 真ん中を入れ替えて門松列
|
ユーザー |
![]() |
提出日時 | 2025-04-16 00:24:01 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,265 bytes |
コンパイル時間 | 249 ms |
コンパイル使用メモリ | 82,244 KB |
実行使用メモリ | 146,548 KB |
最終ジャッジ日時 | 2025-04-16 00:25:10 |
合計ジャッジ時間 | 4,619 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 5 |
other | AC * 5 TLE * 1 -- * 8 |
ソースコード
from collections import defaultdict, deque class Edge: def __init__(self, to, rev, capacity, cost): self.to = to self.rev = rev self.capacity = capacity self.cost = cost class MinCostFlow: def __init__(self, N): self.N = N self.graph = [[] for _ in range(N)] def add_edge(self, fr, to, capacity, cost): forward = Edge(to, len(self.graph[to]), capacity, cost) backward = Edge(fr, len(self.graph[fr]), 0, -cost) self.graph[fr].append(forward) self.graph[to].append(backward) def flow(self, s, t, maxf): INF = float('inf') res = 0 h = [0] * self.N # Potential prevv = [0] * self.N preve = [0] * self.N flow = 0 while maxf > 0: dist = [INF] * self.N inqueue = [False] * self.N dist[s] = 0 q = deque() q.append(s) inqueue[s] = True while q: v = q.popleft() inqueue[v] = False for i, e in enumerate(self.graph[v]): if e.capacity > 0 and dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]: dist[e.to] = dist[v] + e.cost + h[v] - h[e.to] prevv[e.to] = v preve[e.to] = i if not inqueue[e.to]: q.append(e.to) inqueue[e.to] = True if dist[t] == INF: break for v in range(self.N): if dist[v] < INF: h[v] += dist[v] d = maxf v = t while v != s: d = min(d, self.graph[prevv[v]][preve[v]].capacity) v = prevv[v] flow += d res += d * h[t] maxf -= d v = t while v != s: e = self.graph[prevv[v]][preve[v]] e.capacity -= d self.graph[v][e.rev].capacity += d v = prevv[v] return flow, res def main(): import sys input = sys.stdin.read data = input().split() idx = 0 N = int(data[idx]) idx += 1 M = int(data[idx]) idx += 1 groups = [] B_list = [] for _ in range(N): A = int(data[idx]) B = int(data[idx+1]) C = int(data[idx+2]) groups.append((A, B, C)) B_list.append(B) idx +=3 # Count B occurrences cnt = defaultdict(int) for b in B_list: cnt[b] += 1 unique_B = list(cnt.keys()) K = len(unique_B) B_index = {v: i + N + 1 for i, v in enumerate(unique_B)} # Preprocess candidates for each group candidates = [] for i in range(N): A, _, C = groups[i] valid = [] for v in unique_B: if A == v or v == C or A == C: continue max_val = max(A, v, C) min_val = min(A, v, C) mid_val = A + v + C - max_val - min_val if mid_val == A or mid_val == C: valid.append((v, max_val)) # Sort by max_val descending valid.sort(key=lambda x: -x[1]) candidates.append(valid) # Check if any group has no candidates for i in range(N): if not candidates[i]: print("NO") return # Build the flow network S = 0 T = N + K + 1 mcf = MinCostFlow(N + K + 2) # Source to groups for i in range(1, N+1): mcf.add_edge(S, i, 1, 0) # Groups to B nodes for i in range(N): group_id = i + 1 for v, max_val in candidates[i]: b_node = B_index[v] mcf.add_edge(group_id, b_node, 1, -max_val) # Negative for min cost # B nodes to sink for v in unique_B: b_node = B_index[v] cap = cnt[v] mcf.add_edge(b_node, T, cap, 0) # Compute flow flow, cost = mcf.flow(S, T, N) if flow != N: print("NO") else: total = -cost if total >= M: print("YES") print("KADOMATSU!") else: print("YES") print("NO") if __name__ == "__main__": main()