Skip to content

Commit fd55caa

Browse files
authored
Merge pull request cheran-senthil#100 from RedHeadphone/master
add: rerooter
2 parents ffb0243 + 997d443 commit fd55caa

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

pyrival/graphs/rerooter.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
2+
def rerooter(graph, default, combine, finalize=lambda nodeDP, node, eind: nodeDP):
3+
n = len(graph)
4+
rootDP = [0] * n
5+
forwardDP = [None] * n
6+
reverseDP = [None] * n
7+
8+
def exclusive(A, zero, combine, node):
9+
n = len(A)
10+
exclusiveA = [zero] * n
11+
12+
for bit in range(n.bit_length())[::-1]:
13+
for i in range(n)[::-1]:
14+
exclusiveA[i] = exclusiveA[i // 2]
15+
for i in range(n & (-1 if bit else -2)):
16+
ind = (i >> bit) ^ 1
17+
exclusiveA[ind] = combine(exclusiveA[ind], A[i], node, i)
18+
return exclusiveA
19+
20+
DP = [0] * n
21+
bfs = [0]
22+
P = [0] * n
23+
for node in bfs:
24+
for nei in graph[node]:
25+
if P[node] != nei:
26+
P[nei] = node
27+
bfs.append(nei)
28+
29+
for node in reversed(bfs):
30+
nodeDP = default[node]
31+
for eind, nei in enumerate(graph[node]):
32+
if P[node] != nei:
33+
nodeDP = combine(nodeDP, DP[nei], node, eind)
34+
DP[node] = finalize(nodeDP, node, graph[node].index(P[node]) if node else -1)
35+
36+
for node in bfs:
37+
DP[P[node]] = DP[node]
38+
forwardDP[node] = [DP[nei] for nei in graph[node]]
39+
rerootDP = exclusive(forwardDP[node], default[node], combine, node)
40+
reverseDP[node] = [
41+
finalize(nodeDP, node, eind) for eind, nodeDP in enumerate(rerootDP)
42+
]
43+
rootDP[node] = finalize(
44+
(
45+
combine(rerootDP[0], forwardDP[node][0], node, 0)
46+
if n > 1
47+
else default[node]
48+
),
49+
node,
50+
-1,
51+
)
52+
for nei, dp in zip(graph[node], reverseDP[node]):
53+
DP[nei] = dp
54+
return rootDP, forwardDP, reverseDP

0 commit comments

Comments
 (0)