docstr: Add an edge (p, q) to the spanning tree where q is the root of a subtree.
docstr_tok: ["Add","an","edge","(","p",",","q",")","to","the","spanning","tree","where","q","is","the","root","of","a","subtree","."]
code: def add_edge(self, i, p, q):
      """
      Add an edge (p, q) to the spanning tree where q is the root of a subtree.
      """
      last_p = self.last_descendent_dft[p]
      next_last_p = self.next_node_dft[last_p]
      size_q = self.subtree_size[q]
      last_q = self.last_descendent_dft[q]
      # Make q a child of p.
      self.parent[q] = p
      self.parent_edge[q] = i
      # Insert the subtree rooted at q into the depth-first thread.
      self.next_node_dft[last_p] = q
      self.prev_node_dft[q] = last_p
      self.prev_node_dft[next_last_p] = last_q
      self.next_node_dft[last_q] = next_last_p
      # Update the subtree sizes and last descendants of the (new) ancestors
      # of q.
      while p is not None:
          self.subtree_size[p] += size_q
          if self.last_descendent_dft[p] == last_p:
              self.last_descendent_dft[p] = last_q
          p = self.parent[p]
  
imports: from itertools import chain, islice, repeat
  from math import ceil, sqrt
  import networkx
  from networkx.utils import not_implemented_for
label_desc: Use image node_id 10 for calling the _DataEssentialsAndFunctions obj's underlying member method code with example usage: obj.add_edge(i, p, q) without return types