public class Vertex {
  String name; 
  public Vertex(String name) {
    this.name = name; 
  }
  public String toString() {
    return this.name; 
  }
  public boolean equals(Vertex v) {
    return this.name.equals(v.name);  
  }
}

--

import java.util.*;

public class Neighbors extends ArrayList<Vertex> {
  public Neighbors( Vertex[] neighbors ) {
    for (Vertex v : neighbors)
      this.add(v); 
  }
}

--

import java.util.*;

public class Path extends ArrayList<Vertex> {
  public Path() {
    
  }
  public Path(Vertex v) {
    this.add(v);  
  }
  public Path clone() {
    Path a = new Path(); 
    for (Vertex v : this)
      a.add(v); 
    return a; 
  }
}

--

import java.util.*; 

public class Paths extends ArrayList<Path> {
  public Paths() {
    
  }
  public Paths(Path p) {
    this.add(p);  
  }
}

--

import java.util.*; 

public class Graph extends HashMap<Vertex, Neighbors> {
  public Neighbors neighborsOf(Vertex v) {
    return this.get(v);  
  }
  public Path shortestPath(Vertex stop, Paths candidates) {
    System.out.println( candidates ); 
    if (candidates == null) return null;
    else if (candidates.size() == 0) return new Path(); 
    else {
      for (Path candidate : candidates) 
        if (candidate.get(candidate.size() - 1).equals(stop)) 
        return candidate;
      Paths newSet = new Paths(); 
      for (Path c : candidates) {
        Path clone = c.clone(); 
        Neighbors next = neighborsOf( clone.get(clone.size() - 1) );
        System.out.println( next ); 
        for (Vertex v : next ) {
          if (clone.contains(v)) {
            
          } else {
            clone.add(v); 
            newSet.add(clone); 
          }
        }
      }
      return shortestPath(stop, newSet); 
    }
  }
}

--

public class United extends Graph {
  United() {
    Vertex  sf = new Vertex("san francisco"); 
    Vertex   p = new Vertex("portland"); 
    Vertex  la = new Vertex("los angeles"); 
    Vertex slc = new Vertex("salt lake city");  
    Vertex   v = new Vertex("vancouver");  
    Vertex   s = new Vertex("seattle");  
    Vertex   h = new Vertex("helena");  
    Vertex   d = new Vertex("denver");  
    Vertex  lv = new Vertex("las vegas");  
    Vertex sfe = new Vertex("santa fe");  
    Vertex  ph = new Vertex("phoenix");  
    Vertex   e = new Vertex("el paso");  
    
    this.put( sf, new Neighbors(new Vertex[] { p, slc, la } ));  
    this.put(  p, new Neighbors(new Vertex[] { s, slc, sf } ));  
    this.put(slc, new Neighbors(new Vertex[] { h, d, lv, sf, p } ));  
    this.put( la, new Neighbors(new Vertex[] { sf, lv, ph, e } ));  

  }
}

--

public class Example {
  public static void main(String[] args) {
    Graph a = new United(); 
    System.out.println( a ); 
    System.out.println( a.get(new Vertex("san francisco") )); 
    Path p = a.shortestPath(new Vertex("los angeles"), 
                            new Paths(new Path(new Vertex("san francisco")))); 
    System.out.println( p ); 
  }
}