結果
| 問題 | No.1479 Matrix Eraser |
| コンテスト | |
| ユーザー |
yuruhiya
|
| 提出日時 | 2021-04-20 18:09:32 |
| 言語 | Crystal (1.14.0) |
| 結果 |
AC
|
| 実行時間 | 375 ms / 3,000 ms |
| コード長 | 3,927 bytes |
| 記録 | |
| コンパイル時間 | 12,780 ms |
| コンパイル使用メモリ | 300,404 KB |
| 実行使用メモリ | 65,124 KB |
| 最終ジャッジ日時 | 2024-07-04 05:27:44 |
| 合計ジャッジ時間 | 18,539 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 39 |
コンパイルメッセージ
In Main.cr:156:15
156 | edges = Array.product((0...h).to_a, (0...w).to_a).group_by { |(i, j)|
^------
Warning: Deprecated Array(T).product. Use `Indexable.cartesian_product(indexables : Indexable(Indexable))` instead
A total of 1 warnings were found.
ソースコード
# require "template"
lib C
fun strtoll(s : UInt8*, p : UInt8**, b : Int32) : Int64
end
class String
def to_i64
C.strtoll(self, nil, 10)
end
end
# require "graph/bipartite_matching"
# require "./graph"
struct Edge(T)
property to : Int32
property cost : T
def initialize(@to : Int32, @cost : T)
end
def to_s(io) : Nil
io << {to, cost}
end
def inspect(io) : Nil
io << "->#{to}(#{cost})"
end
end
struct Edge2(T)
property from : Int32
property to : Int32
property cost : T
def initialize(@from : Int32, @to : Int32, @cost : T)
end
def reverse
Edge2(T).new(to, from, cost)
end
def to_s(io) : Nil
io << {from, to, cost}
end
def inspect(io) : Nil
io << "#{from}->#{to}(#{cost})"
end
end
class Graph(T)
getter size : Int32
getter graph : Array(Array(Edge(T)))
def initialize(@size : Int32)
raise ArgumentError.new("Negative graph size: #{size}") unless size >= 0
@graph = Array.new(size) { Array(Edge(T)).new }
end
def initialize(@size, edges : Array(Edge2(T)), undirected : Bool)
raise ArgumentError.new("Negative graph size: #{size}") unless size >= 0
@graph = Array.new(size) { Array(Edge(T)).new }
edges.each do |edge|
@graph[edge.from] << Edge.new(edge.to, edge.cost)
@graph[edge.to] << Edge.new(edge.from, edge.cost) if undirected
end
end
def add_edge(i : Int32, j : Int32, cost : T)
raise IndexError.new unless 0 <= i < size
raise IndexError.new unless 0 <= j < size
graph[i] << Edge(T).new(j, cost)
graph[j] << Edge(T).new(i, cost)
end
def add_edge_directed(i : Int32, j : Int32, cost : T)
raise IndexError.new unless 0 <= i < size
raise IndexError.new unless 0 <= j < size
graph[i] << Edge(T).new(j, cost)
end
def [](i : Int32)
graph[i]
end
def each_edge : Nil
(0...size).each do |v|
graph[v].each do |edge|
yield Edge2(T).new(v, edge.to, edge.cost)
end
end
end
def edges : Array(Edge2(T))
result = [] of Edge2(T)
each_edge do |edge|
result << edge
end
result
end
end
class BipartiteMatching
getter left : Int32
getter right : Int32
getter graph : Graph(Nil)
def initialize(@left, @right)
raise ArgumentError.new "Negative left vertexes size: #{left}" unless left >= 0
raise ArgumentError.new "Negative right vertexes size: #{right}" unless right >= 0
@graph = Graph(Nil).new(left)
@left_match = Array(Int32?).new(left, nil)
@right_match = Array(Int32?).new(right, nil)
@used = Array(Bool).new(left, false)
end
def add_edge(l : Int32, r : Int32)
raise IndexError.new unless 0 <= l < left
raise IndexError.new unless 0 <= r < right
graph[l] << Edge.new(r, nil)
self
end
def add_edge(edges : Array(Edge2(Nil)))
edges.each do |edge|
add_edge(edge.from, edge.to)
end
self
end
private def dfs(v : Int32) : Bool
return false if @used[v]
@used[v] = true
graph[v].each do |edge|
if @right_match[edge.to].nil? || dfs(@right_match[edge.to].not_nil!)
@left_match[v], @right_match[edge.to] = edge.to, v
return true
end
end
return false
end
def solve : Int32
while (0...left).reduce(false) { |update, i|
update | (@left_match[i].nil? ? dfs(i) : false)
}
@used.fill(false)
end
left - @left_match.count(&.nil?)
end
end
h, w = read_line.split.map(&.to_i)
a = (1..h).map { read_line.split.map(&.to_i) }
l, r = 0, 0
edges = Array.product((0...h).to_a, (0...w).to_a).group_by { |(i, j)|
a[i][j]
}.flat_map { |val, points|
next [] of Edge2(Nil) if val == 0
row = {} of Int32 => Int32
column = {} of Int32 => Int32
points.map do |(y, x)|
ll = row[y]? || (row[y] = (l += 1) - 1)
rr = column[x]? || (column[x] = (r += 1) - 1)
Edge2.new(ll, rr, nil)
end
}
puts BipartiteMatching.new(l, r).add_edge(edges).solve
yuruhiya