private void shortestPathRecur(List<E> edges, int v_a, int v_b) {
   int k = backtrace[v_a][v_b];
   if (k == -1) {
     E edge = graph.getEdge(vertices.get(v_a), vertices.get(v_b));
     if (edge != null) {
       edges.add(edge);
     }
   } else {
     shortestPathRecur(edges, v_a, k);
     shortestPathRecur(edges, k, v_b);
   }
 }
  private GraphPath<V, E> getShortestPathImpl(V a, V b) {
    int v_a = vertices.indexOf(a);
    int v_b = vertices.indexOf(b);

    List<E> edges = new ArrayList<E>();
    shortestPathRecur(edges, v_a, v_b);

    // no path, return null
    if (edges.size() < 1) {
      return null;
    }

    double weight = 0.;
    for (E e : edges) {
      weight += graph.getEdgeWeight(e);
    }

    GraphPathImpl<V, E> path = new GraphPathImpl<V, E>(graph, a, b, edges, weight);

    return path;
  }