結果

問題 No.416 旅行会社
ユーザー yuruhiyayuruhiya
提出日時 2021-07-11 18:25:12
言語 Crystal
(1.11.2)
結果
AC  
実行時間 341 ms / 4,000 ms
コード長 1,609 bytes
コンパイル時間 23,663 ms
コンパイル使用メモリ 255,724 KB
実行使用メモリ 26,276 KB
最終ジャッジ日時 2023-08-21 10:47:53
合計ジャッジ時間 29,048 ms
ジャッジサーバーID
(参考情報)
judge13 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 214 ms
18,364 KB
testcase_01 AC 2 ms
4,332 KB
testcase_02 AC 2 ms
4,392 KB
testcase_03 AC 3 ms
4,460 KB
testcase_04 AC 3 ms
4,484 KB
testcase_05 AC 3 ms
4,416 KB
testcase_06 AC 3 ms
4,440 KB
testcase_07 AC 4 ms
4,840 KB
testcase_08 AC 8 ms
5,084 KB
testcase_09 AC 28 ms
6,300 KB
testcase_10 AC 212 ms
15,240 KB
testcase_11 AC 211 ms
15,836 KB
testcase_12 AC 215 ms
15,372 KB
testcase_13 AC 210 ms
18,720 KB
testcase_14 AC 341 ms
25,864 KB
testcase_15 AC 326 ms
25,900 KB
testcase_16 AC 326 ms
25,820 KB
testcase_17 AC 330 ms
25,824 KB
testcase_18 AC 333 ms
26,276 KB
testcase_19 AC 279 ms
24,540 KB
testcase_20 AC 280 ms
21,924 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