結果
| 問題 |
No.19 ステージの選択
|
| ユーザー |
|
| 提出日時 | 2022-03-02 19:38:04 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 41 ms / 5,000 ms |
| コード長 | 3,733 bytes |
| コンパイル時間 | 191 ms |
| コンパイル使用メモリ | 81,968 KB |
| 実行使用メモリ | 54,664 KB |
| 最終ジャッジ日時 | 2024-07-16 10:41:43 |
| 合計ジャッジ時間 | 1,846 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 24 |
ソースコード
class SCC():
#index :0-index or 1-index
#逆グラフは自動で作る
def __init__(self,G,index = 1):
self.G = G
self.N = len(G)
self.index = index
self.rG = self.make_reverse()
self.order = []
self.parent = [0] * self.N #各頂点の属する強連結成分の番号
self.num = 0 #強連結成分の数
self.build()
self.sG,self.top,self.Component = self.make_sG()
#sG 縮約後のグラフ。setでつくってある
#top sGをトポロジカルソートしたもの
#Component 各強連結成分に属する頂点をまとめた配列
#逆グラフを作る
def make_reverse(self):
G = self.G
rG = [[] for _ in range(self.N)]
for v in range(self.index,self.N):
for u in G[v]:
rG[u].append(v)
return rG
def build(self):
G = self.G
rG = self.rG
parent = self.parent
order = self.order
memo = [0] * self.N
stack = []
label = 0
for v in range(self.index,self.N):
if memo[v] == 1:continue
stack.append(~v)
stack.append(v)
memo[v] = 1
while stack:
now = stack.pop()
if now >= 0:
for u in G[now]:
if memo[u] == 0:
memo[u] = 1
stack.append(~u)
stack.append(u)
else:
order.append(~now)
memo = [0] * self.N
for v in reversed(order):
if memo[v] == 1:continue
stack.append(v)
memo[v] = 1
parent[v] = label
while stack:
now = stack.pop()
for u in rG[now]:
if memo[u] == 1:
continue
memo[u] = 1
stack.append(u)
parent[u] = label
label += 1
self.num = label
#縮約後のグラフを作る
#トポロジカルソートもする
def make_sG(self):
sG = [set() for _ in range(self.num)]
Component = [[] for _ in range(self.num)]
sGnum = [0] * self.num
G = self.G
parent = self.parent
for v in range(self.index,self.N):
Component[parent[v]].append(v)
for u in G[v]:
if parent[u] == parent[v]:continue
if parent[u] not in sG[parent[v]]:
sG[parent[v]].add(parent[u])
sGnum[parent[u]] += 1
top = []
stack = []
for i in range(self.num):
if sGnum[i] == 0:
stack.append(i)
while stack:
now = stack.pop()
top.append(now)
for v in sG[now]:
sGnum[v] -= 1
if sGnum[v] == 0:
stack.append(v)
return sG,top,Component
N = int(input())
L = [0] * N
G = [[] for _ in range(N)]
for i in range(N):
L[i],s = map(int,input().split())
s -= 1
if i != s:
G[s].append(i)
scc = SCC(G,0)
Comp = scc.Component
top = scc.top
sG = scc.sG
ans = 0
memo = [0] * scc.num
for v in top:
if memo[v] == 1:
for u in Comp[v]:
ans += L[u] / 2
else:
_min = 10 ** 9
index = -1
for u in Comp[v]:
if L[u] < _min:
_min = L[u]
index = u
ans += _min
for u in Comp[v]:
if u != index:
ans += L[u] / 2
for u in sG[v]:
memo[u] = 1
print(ans/1)