Advertisement
manish

lca

Feb 11th, 2021
964
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.04 KB | None | 0 0
  1. class SegmentTree:
  2.     def __init__(self, array):
  3.         self.n = len(array)
  4.         self.size = 1
  5.         while self.size <= n:self.size*=2
  6.         self.func = lambda x, y: x if x[0] < y[0] else y
  7.         self.default = (10**9, -1)
  8.         self.data = [self.default] * (2 * self.size)
  9.         self.process(array)
  10.  
  11.     def process(self, array):
  12.         self.data[self.size : self.size+self.n] = array
  13.         for i in range(self.size-1, -1, -1):
  14.             self.data[i] = self.func(self.data[2*i], self.data[2*i+1])
  15.  
  16.     def query(self, alpha, omega):
  17.         """Returns the result of function over the range (inclusive)!"""
  18.         if alpha == omega:
  19.             return self.data[alpha + self.size]
  20.         res = self.default
  21.         alpha += self.size
  22.         omega += self.size + 1
  23.         while alpha < omega:
  24.             if alpha & 1:
  25.                 res = self.func(res, self.data[alpha])
  26.                 alpha += 1
  27.             if omega & 1:
  28.                 omega -= 1
  29.                 res = self.func(res, self.data[omega])
  30.             alpha >>= 1
  31.             omega >>= 1
  32.         return res
  33.  
  34.     def update(self, index, value):
  35.         """Updates the element at index to given value!"""
  36.         index += self.size
  37.         self.data[index] = value
  38.         index >>= 1
  39.         while index:
  40.             self.data[index] = self.func(self.data[2*index], self.data[2*index+1])
  41.             index >>= 1
  42.  
  43. class LCA:
  44.     def __init__(self, graph, root):
  45.         self.graph= graph
  46.         self.n = len(graph)
  47.         self.euler = []
  48.         self.first = [-1]*self.n
  49.         self.st = None
  50.         self.dfs(root)
  51.         self.process()
  52.  
  53.     def dfs(self, root):
  54.         visited, parents, heights = [False]*self.n, [-1]*self.n, [1]*self.n
  55.         stack = [root]
  56.         while stack:
  57.             v = stack[-1]
  58.             if not visited[v]:
  59.                 visited[v] = True
  60.                 self.euler += [v]
  61.                 if self.first[v] == -1:
  62.                     self.first[v] = len(self.euler) - 1
  63.                 for u in graph[v]:
  64.                     if not visited[u]:
  65.                         stack.append(u)
  66.                         parents[u], heights[u] = v, heights[v] + 1
  67.             else:
  68.                 self.euler += [parents[stack.pop()]]
  69.         self.euler = [(heights[k], k) for k in self.euler]
  70.  
  71.     def process(self):
  72.         self.st = SegmentTree(self.euler)
  73.  
  74.     def query(self, x, y):
  75.         """Returns the lowest common ancestor of nodes x and y!"""
  76.         p, q = min(self.first[x], self.first[y]), max(self.first[x], self.first[y])
  77.         return self.st.query(p, q)[1]
  78.  
  79. import sys
  80. input = sys.stdin.readline
  81. for _ in range(1, int(input()) + 1):
  82.     n = int(input())
  83.     graph = [[] for __ in range(n+1)]
  84.     for i in range(1, n+1):
  85.         for j in list(map(int, input().split()))[1:]:
  86.             graph[i] += [j]
  87.             graph[j] += [i]
  88.     lca = LCA(graph, 1)
  89.     print("Case %d:" % _)
  90.     for __ in range(int(input())):
  91.         x, y = map(int, input().split())
  92.         print(lca.query(x, y))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement