結果
| 問題 |
No.1660 Matrix Exponentiation
|
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2022-03-29 21:37:17 |
| 言語 | Lua (LuaJit 2.1.1734355927) |
| 結果 |
AC
|
| 実行時間 | 610 ms / 2,000 ms |
| コード長 | 4,558 bytes |
| コンパイル時間 | 73 ms |
| コンパイル使用メモリ | 5,120 KB |
| 実行使用メモリ | 82,080 KB |
| 最終ジャッジ日時 | 2024-11-08 20:04:14 |
| 合計ジャッジ時間 | 5,460 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 27 |
ソースコード
local mmi, mma = math.min, math.max
local SCCD = {}
SCCD.create = function(self, n)
self.n = n
self.asked, self.root = {}, {}
self.edge, self.edge_asked = {}, {}
self.invedge, self.invedge_asked = {}, {}
for i = 1, n do
self.asked[i] = false
self.root[i] = 0
self.edge[i] = {}
self.edge_asked[i] = 0
self.invedge[i] = {}
self.invedge_asked[i] = 0
end
self.edgeinfo = {}
end
SCCD.addEdge = function(self, src, dst)
table.insert(self.edge[src], dst)
table.insert(self.invedge[dst], src)
table.insert(self.edgeinfo, src)
table.insert(self.edgeinfo, dst)
end
SCCD.dfs = function(self, spos, dfs_way)
local asked = self.asked
local edge, edge_asked = self.edge, self.edge_asked
local tasks = {spos}
while 0 < #tasks do
local src = tasks[#tasks]
asked[src] = true
table.remove(tasks)
if edge_asked[src] == #edge[src] then
table.insert(dfs_way, src)
else
table.insert(tasks, src)
edge_asked[src] = edge_asked[src] + 1
local dst = edge[src][edge_asked[src]]
if not asked[dst] then
table.insert(tasks, dst)
end
end
end
end
SCCD.invdfs = function(self, spos, rootid)
local asked, root = self.asked, self.root
local invedge, invedge_asked = self.invedge, self.invedge_asked
local tasks = {spos}
while 0 < #tasks do
local src = tasks[#tasks]
root[src] = rootid
table.remove(tasks)
while invedge_asked[src] < #invedge[src] do
invedge_asked[src] = invedge_asked[src] + 1
local dst = invedge[src][invedge_asked[src]]
if asked[dst] and root[dst] == 0 then
table.insert(tasks, src)
table.insert(tasks, dst)
break
end
end
end
end
SCCD.categorize = function(self)
local asked, root = self.asked, self.root
for src = 1, self.n do
if not asked[src] then
local dfs_way = {}
self:dfs(src, dfs_way)
for i = #dfs_way, 1, -1 do
local src = dfs_way[i]
if root[src] == 0 then
self:invdfs(src, src)
end
end
end
end
end
SCCD.make_group_graph = function(self)
self.gsize = {}
self.gedge = {}
self.gpcnt = {}
self.glen = {}
self.gmember = {}
local gsize, gmember, glen = self.gsize, self.gmember, self.glen
local gedge, gpcnt = self.gedge, self.gpcnt
local root = self.root
local edgeinfo = self.edgeinfo
for i = 1, self.n do
gsize[i] = 0
gedge[i], gpcnt[i] = {}, 0
glen[i] = 1
gmember[i] = {}
end
for i = 1, self.n do
local r = root[i]
gsize[r] = gsize[r] + 1
table.insert(gmember[r], i)
end
for i = 1, #edgeinfo, 2 do
local a, b = edgeinfo[i], edgeinfo[i + 1]
local ra, rb = root[a], root[b]
if ra ~= rb then
glen[rb] = mma(glen[rb], glen[ra] + 1)
table.insert(gedge[ra], rb)
gpcnt[rb] = gpcnt[rb] + 1
end
end
end
SCCD.toposort = function(self)
self:make_group_graph()
local gsize, gedge, gpcnt = self.gsize, self.gedge, self.gpcnt
local topoary = {}
self.topoary = topoary
local topo_tasks = {}
for i = 1, self.n do
if 0 < gsize[i] and gpcnt[i] == 0 then
table.insert(topo_tasks, i)
end
end
local topo_done = 0
while topo_done < #topo_tasks do
topo_done = topo_done + 1
local g = topo_tasks[topo_done]
topoary[topo_done] = g
for i = 1, #gedge[g] do
local dst = gedge[g][i]
gpcnt[dst] = gpcnt[dst] - 1
if gpcnt[dst] == 0 then
table.insert(topo_tasks, dst)
end
end
end
return topoary
end
SCCD.new = function(n)
local obj = {}
setmetatable(obj, {__index = SCCD})
obj:create(n)
return obj
end
local n, m = io.read("*n", "*n")
local edge, pcnt = {}, {}
for i = 1, n do
edge[i] = {}
pcnt[i] = 0
end
local sccd = SCCD.new(n)
for i = 1, m do
local a, b = io.read("*n", "*n")
sccd:addEdge(a, b)
if a == b then print(-1) os.exit() end
table.insert(edge[a], b)
pcnt[b] = pcnt[b] + 1
end
sccd:categorize()
local ary = sccd:toposort()
for i = 1, #ary do
local r = ary[i]
if 1 < #sccd.gmember[r] then
print(-1) os.exit()
end
end
local tasks = {}
local len = {}
for i = 1, n do
len[i] = 1
if pcnt[i] == 0 then
table.insert(tasks, i)
end
end
local done = 0
while done < #tasks do
done = done + 1
local src = tasks[done]
for i = 1, #edge[src] do
local dst = edge[src][i]
len[dst] = mma(len[dst], len[src] + 1)
pcnt[dst] = pcnt[dst] - 1
if pcnt[dst] == 0 then
table.insert(tasks, dst)
end
end
end
local ret = 1
for i = 1, n do
ret = mma(ret, len[i])
end
print(ret)