結果
| 問題 |
No.416 旅行会社
|
| コンテスト | |
| ユーザー |
yuruhiya
|
| 提出日時 | 2021-07-11 18:25:12 |
| 言語 | Crystal (1.14.0) |
| 結果 |
AC
|
| 実行時間 | 320 ms / 4,000 ms |
| コード長 | 1,609 bytes |
| コンパイル時間 | 16,069 ms |
| コンパイル使用メモリ | 297,516 KB |
| 実行使用メモリ | 17,684 KB |
| 最終ジャッジ日時 | 2024-12-14 21:11:48 |
| 合計ジャッジ時間 | 20,223 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 21 |
ソースコード
# require "/datastructure/PartiallyPersistentUnionFind"
class PartiallyPersistentUnionFind
getter size : Int32, now : Int32
def initialize(size : Int)
@size = size.to_i
@now = 0
@parent = Array(Int32).new(size, &.itself)
@rank = Array(Int32).new(size, 0)
@time = Array(Int32).new(size, Int32::MAX)
@num = Array(Array({Int32, Int32})).new(size) { [{0, 1}] }
end
def root(x : Int, time : Int) : Int32
time < @time[x] ? x : root(@parent[x], time)
end
def same?(x : Int, y : Int, time : Int) : Bool
root(x, time) == root(y, time)
end
def unite(x : Int, y : Int) : Bool
@now += 1
x, y = root(x, now), root(y, now)
return false if x == y
x, y = y, x if @rank[x] < @rank[y]
@num[x] << {now, size(x, now) + size(y, now)}
@parent[y] = x
@time[y] = now
@rank[x] += 1 if @rank[x] == @rank[y]
true
end
def size(x : Int, time : Int) : Int
x = root(x, time)
pos = @num[x].bsearch_index { |(t, s), i| t > time } || @num[x].size
@num[x][pos - 1][1]
end
end
n, m, q = read_line.split.map(&.to_i)
ab = Array.new(m) {
{Int32, Int32}.from read_line.split.map(&.to_i.pred)
}
cd = Array.new(q) {
{Int32, Int32}.from read_line.split.map(&.to_i.pred)
}
ab -= cd
uf = PartiallyPersistentUnionFind.new(n)
(ab - cd).each do |a, b|
uf.unite(a, b)
end
begin_time = uf.now
cd.reverse_each do |c, d|
uf.unite(c, d)
end
end_time = uf.now
(1...n).each do |i|
t = (begin_time..end_time).bsearch { |t| uf.same?(0, i, t) }
if t.nil?
puts 0
elsif t == begin_time
puts -1
else
puts end_time - t + 1
end
end
yuruhiya