import java.io.*; import java.util.*; class Node { String city; Set roads; public String toString(){ return "NODE: "+city+" with "+roads; } } class Edge { String road; String dest; Hashtable costs; public boolean equals (Object o){ Edge x = (Edge) o; return road.equals(x.road) && dest.equals(x.dest); } public int hashCode(){ return road.hashCode() + dest.hashCode(); } public String toString(){ return "road "+road+" to "+dest; } } class Path { String source; String road; public String toString(){ return source+" via "+road; } } public class map { public static String TIME = "time"; public static String DIST = "dist"; public static String TURNS = "turn"; public static void main(String[] argv) throws Exception { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); Hashtable cityGraph = new Hashtable(); Hashtable roadGraph = new Hashtable(); int Ncities = Integer.parseInt(in.readLine().trim()); for(int i=0;i newWeight){ costTo.put(road.dest, new Double(newWeight)); Path p = new Path(); p.source = curNode.city; p.road = road.road; predecessors.put(road.dest, p); } } } double mincost=Double.MAX_VALUE; String minCity=null; for(Iterator doCosts = costTo.keySet().iterator(); doCosts.hasNext();){ String city = (String) doCosts.next(); double thisCost = ((Double)costTo.get(city)).doubleValue(); if(thisCost< mincost){ mincost = thisCost; minCity = city; } } curNode = (Node) graph.get(minCity); costTo.put(minCity, new Double(Double.MAX_VALUE)); currentWeight = mincost; visited.add(curNode.city); } return predecessors; } static String shortestRoadPath(Hashtable graph, String startCity, String destCity, String costtype, Hashtable predecessors){ Hashtable costTo = new Hashtable(); Set visited = new HashSet(); Node curNode = (Node) graph.get(startCity); double currentWeight = 0; visited.add(startCity); while(true){ for(Iterator doC = curNode.roads.iterator(); doC.hasNext();){ Edge road = (Edge) doC.next(); if(road.road.equals(destCity)) return curNode.city; if(!visited.contains(road.dest)){ double newWeight = currentWeight + ((Double)road.costs.get(costtype)).doubleValue(); double oldWeight = Double.MAX_VALUE; if(costTo.get(road.dest)!=null) oldWeight = ((Double)costTo.get(road.dest)).doubleValue(); if( oldWeight > newWeight){ costTo.put(road.dest, new Double(newWeight)); Path p = new Path(); p.source = curNode.city; p.road = road.road; predecessors.put(road.dest, p); } } } double mincost; String minCity=null; mincost=Double.MAX_VALUE; for(Iterator doCosts = costTo.keySet().iterator(); doCosts.hasNext();){ String city = (String) doCosts.next(); double thisCost = ((Double)costTo.get(city)).doubleValue(); if(thisCost< mincost){ mincost = thisCost; minCity = city; } } curNode = (Node) graph.get(minCity); costTo.put(minCity, new Double(Double.MAX_VALUE)); currentWeight = mincost; visited.add(curNode.city); } } static String recursePath(String startCity, String destCity, Hashtable predecessors){ Path p = (Path) predecessors.get(destCity); if(!p.source.equals(startCity)){ String lastRoad = recursePath(startCity, p.source, predecessors); if(!lastRoad.equals(p.road)) System.out.println(lastRoad+" to "+p.source); } return p.road; } static int pathCount(String startCity,String lastRoute, Hashtable predecessors){ Path p = (Path) predecessors.get(lastRoute); if(p!= null) return pathCount(startCity, p.source, predecessors) + 1; else return 0; } static String recurseRoadPath(String startCity,String lastRoute, Hashtable predecessors){ Path p = (Path) predecessors.get(lastRoute); if(p!=null){ recurseRoadPath(startCity, p.source, predecessors); System.out.println(p.source+" to "+p.road); } return null; } }