結果

問題 No.416 旅行会社
ユーザー 👑 obakyanobakyan
提出日時 2021-08-29 00:04:12
言語 Lua
(LuaJit 2.1.1696795921)
結果
AC  
実行時間 837 ms / 4,000 ms
コード長 2,736 bytes
コンパイル時間 182 ms
コンパイル使用メモリ 4,916 KB
実行使用メモリ 38,788 KB
最終ジャッジ日時 2023-08-21 10:46:09
合計ジャッジ時間 8,047 ms
ジャッジサーバーID
(参考情報)
judge13 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 253 ms
33,944 KB
testcase_01 AC 1 ms
4,376 KB
testcase_02 AC 1 ms
4,380 KB
testcase_03 AC 1 ms
4,380 KB
testcase_04 AC 1 ms
4,376 KB
testcase_05 AC 2 ms
4,376 KB
testcase_06 AC 3 ms
4,380 KB
testcase_07 AC 5 ms
4,376 KB
testcase_08 AC 15 ms
4,380 KB
testcase_09 AC 39 ms
5,972 KB
testcase_10 AC 292 ms
34,044 KB
testcase_11 AC 301 ms
33,912 KB
testcase_12 AC 310 ms
36,016 KB
testcase_13 AC 237 ms
33,876 KB
testcase_14 AC 634 ms
38,700 KB
testcase_15 AC 602 ms
38,580 KB
testcase_16 AC 583 ms
38,560 KB
testcase_17 AC 604 ms
38,752 KB
testcase_18 AC 609 ms
38,788 KB
testcase_19 AC 623 ms
34,512 KB
testcase_20 AC 837 ms
34,556 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

local mfl, mce = math.floor, math.ceil
-- Partially Persistent Union-Find
local PPUF = {}
PPUF.create = function(self, n, inf)
  if not inf then inf = 1000000007 end
  self.inf = inf
  self.parent = {}
  self.updated_time = {}
  self.rank = {}
  self.weight_change_time = {}
  self.weight = {}
  for i = 1, n do
    self.parent[i] = 0
    self.updated_time[i] = inf
    self.rank[i] = 1
    self.weight_change_time[i] = {0}
    -- change weight if need
    self.weight[i] = {1}
  end
  self.edgecnt = 0
end

PPUF.getRoot = function(self, v, tm)
  if not tm then tm = self.edgecnt end
  while self.updated_time[v] <= tm do
    v = self.parent[v]
  end
  return v
end

PPUF.unite = function(self, v1, v2)
  local r1, r2 = self:getRoot(v1), self:getRoot(v2)
  local ec = self.edgecnt + 1
  self.edgecnt = ec
  if r1 == r2 then return end
  local rank = self.rank
  if rank[r2] < rank[r1] then r1, r2 = r2, r1 end
  self.parent[r1] = r2
  self.updated_time[r1] = ec
  if rank[r1] == rank[r2] then
    rank[r2] = rank[r2] + 1
  end
  local weight = self.weight
  local new_w = weight[r2][#weight[r2]] + weight[r1][#weight[r1]]
  table.insert(self.weight_change_time[r2], ec)
  table.insert(weight[r2], new_w)
end

PPUF.getWeight = function(self, v, tm)
  if not tm then tm = self.edgecnt end
  local r = self:getRoot(v, tm)
  local wct = self.weight_change_time[r]
  if wct[#wct] <= tm then return self.weight[r][#wct] end
  local left, right = 1, #wct
  while 1 < right - left do
    local mid = mfl((left + right) / 2)
    if wct[mid] <= tm then
      left = mid
    else
      right = mid
    end
  end
  return self.weight[r][left]
end

PPUF.new = function()
  local obj = {}
  setmetatable(obj, {__index = PPUF})
  return obj
end

local n, m, q = io.read("*n", "*n", "*n")
local edge = {}
local parent = {}
for i = 1, n do
  edge[i] = {}
  parent[i] = i
end
for i = 1, m do
  local a, b = io.read("*n", "*n")
  edge[a][b] = true
end
local cq, dq = {}, {}
for i = 1, q do
  local c, d = io.read("*n", "*n")
  cq[i], dq[i] = c, d
  edge[c][d] = nil
end

local ppuf = PPUF.new()
ppuf:create(n)
local tm = 0
for i = 1, n do
  for j, _u in pairs(edge[i]) do
    ppuf:unite(i, j)
    tm = tm + 1
  end
end
local basetime = tm
for iq = q, 1, -1 do
  local c, d = cq[iq], dq[iq]
  ppuf:unite(c, d)
end

local function solve(j, t)
  return ppuf:getRoot(1, t) == ppuf:getRoot(j, t)
end

local ret = {}
for i = 2, n do
  local ng = 0
  local ok = basetime + q + 1
  while 1 < ok - ng do
    local mid = mfl((ok + ng) / 2)
    if solve(i, mid) then
      ok = mid
    else
      ng = mid
    end
  end
  if ok <= basetime then
    print(-1)
  elseif basetime + q < ok then
    print(0)
  else
    ok = ok - basetime
    print(q + 1 - ok)
  end
end
0