Advertisement
wrequiems

Untitled

Apr 19th, 2019
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.33 KB | None | 0 0
  1. n, q = map(int, input().split(' '))
  2. graph = {}
  3. for i in range(n):
  4.     x, y = [int(i) for i in input().split(' ')]
  5.     graph.setdefault(x, [])
  6.     graph.setdefault(y, [])
  7.     graph[x].append(y)
  8.     graph[y].append(x)
  9.  
  10. visited = [False] * (n + 1)
  11. parent = [None] * (n + 1)
  12. cycle = []
  13. is_on_cycle = [False] * (n + 1)
  14. done = False
  15.  
  16. def compute_cycle(x):
  17.     global done
  18.     visited[x] = True
  19.     for node in graph[x]:
  20.         if done:
  21.             return
  22.         if parent[x] == node:
  23.             continue
  24.         if visited[node]:
  25.             cycle.append(x)
  26.             is_on_cycle[x] = True
  27.             while x != node:
  28.                 x = parent[x]
  29.                 cycle.append(x)
  30.                 is_on_cycle[x] = True
  31.             done = True
  32.             return
  33.         parent[node] = x
  34.         compute_cycle(node)
  35.  
  36. compute_cycle(1)
  37.  
  38.  
  39. position_on_cycle = [None] * (n + 1)
  40.  
  41. distance_to_cycle = [0] * (n + 1)
  42. hits_node_in_cycle = [0] * (n + 1)
  43.  
  44. for i in range(len(cycle)):
  45.     position_on_cycle[cycle[i]] = i
  46.  
  47. def max_distance_on_cycle(x, y):
  48.     a = position_on_cycle[x]
  49.     b = position_on_cycle[y]
  50.     d = abs(a - b)
  51.     return max(d, len(cycle) - d)
  52.  
  53. visited = [False] * (n + 1)
  54. def compute_distance_to_cycle(cycle_node, current_node, distance):
  55.     distance_to_cycle[current_node] = distance
  56.     hits_node_in_cycle[current_node] = cycle_node
  57.     visited[current_node] = True
  58.     for node in graph[current_node]:
  59.         if not visited[node] and not is_on_cycle[node]:
  60.             compute_distance_to_cycle(cycle_node, node, distance + 1)
  61.  
  62.  
  63. for x in cycle:
  64.     for node in graph[x]:
  65.         if not is_on_cycle[node]:
  66.             compute_distance_to_cycle(x, node, 1)
  67.  
  68. def get_distance(a, b):
  69.     if is_on_cycle[a] and is_on_cycle[b]:
  70.         return max_distance_on_cycle(a, b)
  71.     if hits_node_in_cycle[a] == hits_node_in_cycle[b]:
  72.         return 'LCA'
  73.     a_hit = a
  74.     a_distance = 0
  75.     if not is_on_cycle[a]:
  76.         a_hit = hits_node_in_cycle[a]
  77.         a_distance = distance_to_cycle[a]
  78.     b_hit = b
  79.     b_distance = 0
  80.     if not is_on_cycle[b]:
  81.         b_hit = hits_node_in_cycle[b]
  82.         b_distance = distance_to_cycle[b]
  83.     return a_distance + b_distance + max_distance_on_cycle(a_hit, b_hit)
  84.  
  85. for _ in range(q):
  86.     a, b = [int(i) for i in input().split(' ')]
  87.     print(get_distance(a, b))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement