// inserts a undirected edge into the graph
 public void addEdge(UndirectedEdge e) {
   int v = e.either();
   int w = e.other(v);
   adj[v].add(e);
   adj[w].add(e);
   edges++;
 }
  /**
   * Given the edge-weighted graph, it find the minimum spanning tree and its weight.
   *
   * @param graph
   */
  public KruskalMinimumSpanningTree(EdgeWeightedUndirectedGraph graph) {

    MinimumPriorityQueue minEdges = new MinimumPriorityQueue<UndirectedEdge>();
    for (UndirectedEdge edge : graph.edgesIterator()) {
      minEdges.insert(edge);
    }

    int numEdges = 0;

    UnionFind unionFind = new UnionFind(graph.vertices());
    while (!minEdges.isEmpty() && numEdges < graph.vertices() - 1) {

      UndirectedEdge edge = (UndirectedEdge) minEdges.deleteMin();
      int v = edge.vertexA();
      int w = edge.vertexB();

      if (!unionFind.connected(v, w)) {
        unionFind.union(v, w);
        minimumSpanningTree.enqueue(edge);
        numEdges++;
        weight += edge.weight();
      }
    }
  }