結果
| 問題 |
No.1479 Matrix Eraser
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-04-17 15:18:06 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 723 ms / 3,000 ms |
| コード長 | 3,413 bytes |
| コンパイル時間 | 170 ms |
| コンパイル使用メモリ | 82,384 KB |
| 実行使用メモリ | 145,152 KB |
| 最終ジャッジ日時 | 2024-07-03 22:56:11 |
| 合計ジャッジ時間 | 18,021 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 39 |
ソースコード
# Reference: https://tjkendev.github.io/procon-library/python/max_flow/dinic.html
# Max Flow
# 0-indexed
from collections import deque
from sys import setrecursionlimit
setrecursionlimit(10**9)
class Dinic:
def __init__(self, n):
self.n = n
self.G = [[] for _ in range(n)]
def add_edge(self, fr, to, cap):
forward = [to, cap, None]
forward[2] = backward = [fr, 0, forward]
self.G[fr].append(forward)
self.G[to].append(backward)
def bfs(self, s, t):
self.level = level = [None] * self.n
deq = deque([s])
level[s] = 0
G = self.G
while deq:
v = deq.popleft()
lv = level[v] + 1
for w, cap, _ in G[v]:
if cap and level[w] is None:
level[w] = lv
deq.append(w)
return level[t] is not None
def dfs(self, v, t, f):
if v == t:
return f
level = self.level
for edge in self.it[v]:
w, cap, rev = edge
if cap and level[v] < level[w]:
d = self.dfs(w, t, min(f, cap))
if d:
edge[1] -= d
rev[1] += d
return d
return 0
def flow(self, s, t, inf=1<<30):
flow = 0
G = self.G
while self.bfs(s, t):
*self.it, = map(iter, self.G)
f = inf
while f:
f = self.dfs(s, t, inf)
flow += f
return flow
###
# Reference: https://www.slideshare.net/drken1215/ss-86894312
###
from collections import defaultdict
from sys import stdin
input = stdin.readline
def main():
h, w = map(int, input().split())
a = [list(map(int, input().split())) for _ in range(h)]
groups = defaultdict(list)
for i in range(h):
for j in range(w):
groups[a[i][j]].append(w*i + j)
if 0 in groups:
groups.pop(0)
ans = 0
for lis in groups.values():
rows = dict()
columns = dict()
for i in lis:
if i//w not in rows:
rows[i//w] = len(rows)
if i%w not in columns:
columns[i%w] = len(columns)
# Max Flow
# s >>> rows >>> columns >>> t
s = len(rows)+len(columns)
t = s + 1
mf = Dinic(t+1)
for value in rows.values():
mf.add_edge(s, value, 1)
for value in columns.values():
mf.add_edge(value+len(rows), t, 1)
for i in lis:
mf.add_edge(rows[i//w], columns[i%w]+len(rows), 1)
mf.flow(s, t, len(lis))
edges = [[] for _ in range(s)]
todo = []
for i in range(len(rows)):
for j, cap, rev in mf.G[i]:
if j == s or j == t:
continue
if rev[1]:
edges[i].append(j)
else:
edges[j].append(i)
todo.append(i)
seen = [0] * s
for start in todo:
seen[start] = 1
while todo:
i = todo.pop()
for j in edges[i]:
if seen[j]:
continue
seen[j] = 1
todo.append(j)
ans += seen[:len(rows)].count(0) + seen[len(rows):].count(1)
print(ans)
main()