code: def approx_min_num_components(nodes, negative_edges):
      import utool as ut
      num = 0
      g_neg = nx.Graph()
      g_neg.add_nodes_from(nodes)
      g_neg.add_edges_from(negative_edges)
      if nx.__version__.startswith('2'):
          deg0_nodes = [n for n, d in g_neg.degree() if d == 0]
      else:
          deg0_nodes = [n for n, d in g_neg.degree_iter() if d == 0]
      for u, v in ut.itertwo(deg0_nodes):
          nx_contracted_nodes(g_neg, v, u, inplace=True)
      unused = list(g_neg.nodes())
      g_pos = nx.complement(g_neg)
      if False:
          from networkx.algorithms.approximation import clique
          maxiset, cliques = clique.clique_removal(g_pos)
          num = len(cliques)
          return num
      while len(unused) > 0:
          num += 1
          idx1 = 0
          n1 = unused[idx1]
          unused.remove(n1)
          neigbs = list(g_pos.neighbors(n1))
          neigbs = ut.isect(neigbs, unused)
          while len(neigbs) > 0:
              idx2 = 0
              n2 = neigbs[idx2]
              unused.remove(n2)
              g_neg = nx.contracted_nodes(g_neg, n1, n2)
              g_pos = nx.complement(g_neg)
              neigbs = list(g_pos.neighbors(n1))
              neigbs = ut.isect(neigbs, unused)
      print('num = %r' % (num,))
      return num