結果

問題 No.416 旅行会社
ユーザー yuruhiyayuruhiya
提出日時 2021-07-11 18:25:12
言語 Crystal
(1.11.2)
結果
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
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 205 ms
13,824 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 2 ms
5,248 KB
testcase_04 AC 2 ms
5,248 KB
testcase_05 AC 2 ms
5,248 KB
testcase_06 AC 2 ms
5,248 KB
testcase_07 AC 3 ms
5,248 KB
testcase_08 AC 8 ms
5,248 KB
testcase_09 AC 28 ms
5,248 KB
testcase_10 AC 209 ms
13,788 KB
testcase_11 AC 210 ms
13,056 KB
testcase_12 AC 214 ms
13,952 KB
testcase_13 AC 204 ms
12,928 KB
testcase_14 AC 320 ms
17,664 KB
testcase_15 AC 299 ms
17,608 KB
testcase_16 AC 307 ms
17,640 KB
testcase_17 AC 310 ms
17,684 KB
testcase_18 AC 312 ms
17,608 KB
testcase_19 AC 265 ms
17,280 KB
testcase_20 AC 268 ms
17,408 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

# 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
0