結果
| 問題 | No.2263 Perms |
| コンテスト | |
| ユーザー |
detteiuu
|
| 提出日時 | 2026-08-07 23:56:37 |
| 言語 | PyPy3 (7.3.17) |
| 結果 |
AC
|
| 実行時間 | 122 ms / 2,000 ms |
| + 530µs | |
| コード長 | 5,394 bytes |
| 記録 | |
| コンパイル時間 | 418 ms |
| コンパイル使用メモリ | 96,108 KB |
| 実行使用メモリ | 86,912 KB |
| 最終ジャッジ日時 | 2026-08-07 23:56:45 |
| 合計ジャッジ時間 | 6,532 ms |
|
ジャッジサーバーID (参考情報) |
judge1_0 / judge3_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 39 |
ソースコード
import sys
sys.setrecursionlimit(10**6)
from collections import deque
class HopcroftKarp:
def __init__(self, N1, N2):
self.N1 = N1
self.N2 = N2
self.G = [[] for _ in range(self.N1+1)]
self.pair1 = [0]*(self.N1+1)
self.pair2 = [0]*(self.N2+1)
self.matching_size = -1
def add_edge(self, fr, to):
self.G[fr].append(to)
def bfs(self):
que = deque()
for i in range(1, self.N1+1):
if self.pair1[i] == 0:
self.dist[i] = 0
que.append(i)
else:
self.dist[i] = INF
self.dist[0] = INF
while que:
n = que.popleft()
if self.dist[n] < self.dist[0]:
for v in self.G[n]:
if self.dist[self.pair2[v]] == INF:
self.dist[self.pair2[v]] = self.dist[n]+1
que.append(self.pair2[v])
return self.dist[0] != INF
def dfs(self, n):
if n != 0:
for v in self.G[n]:
if self.dist[self.pair2[v]] == self.dist[n]+1:
if self.dfs(self.pair2[v]):
self.pair2[v] = n
self.pair1[n] = v
return True
self.dist[n] = INF
return False
return True
def flow(self):
if self.matching_size != -1:
return self.matching_size
self.dist = [0]*(self.N1+1)
ans = 0
while self.bfs():
for i in range(1, self.N1+1):
if self.pair1[i] == 0 and self.dfs(i):
ans += 1
self.matching_size = ans
return ans
def get_matching(self):
if self.matching_size == -1:
self.flow()
ans = []
for i in range(1, self.N1+1):
if self.pair1[i] != 0:
ans.append((i, self.pair1[i]))
return ans
def minimum_vertex_cover(self):
if self.matching_size == -1:
self.flow()
return self.matching_size
def maximum_independent_set(self):
return self.N1+self.N2-self.minimum_vertex_cover()
def minimum_edge_cover(self):
F = [False]*(self.N1+self.N2+1)
for n in range(1, self.N1+1):
F[n] = True
for v in self.G[n]:
F[self.N1+v] = True
if sum(F) < self.N1+self.N2:
return -1
if self.matching_size == -1:
self.flow()
return self.N1+self.N2-self.matching_size
def preparation(self):
if self.matching_size == -1:
self.flow()
L = self.N1+self.N2
G = [[] for _ in range(L+1)]
for n in range(1, self.N1+1):
for v in self.G[n]:
if self.pair1[n] == v:
G[self.N1+v].append(n)
else:
G[n].append(self.N1+v)
visited = [False]*(L+1)
que = deque()
for i in range(1, self.N1+1):
if self.pair1[i] == 0:
visited[i] = True
que.append(i)
while que:
n = que.popleft()
for v in G[n]:
if not visited[v]:
visited[v] = True
que.append(v)
return visited
def get_minimum_vertex_cover(self):
visited = self.preparation()
ans1 = []
ans2 = []
for i in range(1, self.N1+self.N2+1):
if i <= self.N1 and not visited[i]:
ans1.append(i)
elif self.N1+1 <= i and visited[i]:
ans2.append(i-self.N1)
return ans1, ans2
def get_maximum_independent_set(self):
visited = self.preparation()
ans1 = []
ans2 = []
for i in range(1, self.N1+self.N2+1):
if i <= self.N1 and visited[i]:
ans1.append(i)
elif self.N1+1 <= i and not visited[i]:
ans2.append(i-self.N1)
return ans1, ans2
def get_minimum_edge_cover(self):
cnt = self.minimum_edge_cover()
if cnt == -1:
return None
ans = []
pair = [-1]*(self.N1+self.N2+1)
for n in range(1, self.N1+1):
pair[n] = self.G[n][0]
for v in self.G[n]:
if pair[self.N1+v] == -1:
pair[self.N1+v] = n
for i in range(1, self.N1+self.N2+1):
if i <= self.N1 and self.pair1[i] != 0:
ans.append((i, self.pair1[i]))
elif i <= self.N1 and self.pair1[i] == 0:
ans.append((i, pair[i]))
elif self.N1+1 <= i and self.pair2[i-self.N1] == 0:
ans.append((pair[i], i-self.N1))
return ans
INF = 1<<60
N, M = map(int, input().split())
A = [list(map(int, input().split())) for _ in range(N)]
B = list(map(list, zip(*A)))
if any(sum(a) != M for a in A) or any(sum(b) != M for b in B):
exit(print(-1))
ans = []
for _ in range(M):
H = HopcroftKarp(N, N)
for i in range(N):
for j in range(N):
if A[i][j]:
H.add_edge(i+1, j+1)
matching = H.get_matching()
res = [-1]*N
for a, b in matching:
a, b = a-1, b-1
res[a] = b+1
A[a][b] -= 1
ans.append(res)
for a in ans:
print(*a)
detteiuu