// java -Xms1000M import java.util.*; public class NittaD { static boolean long_mode = false; static boolean debug = false; public static void main(String[] args) { Scanner sc = new Scanner(System.in); for (int i=0; i 25 && h > 25) fc.solve(); } } static class FindCost { public static final int GoStraight = 0; public static final int RightFace = 1; public static final int AboutFace = 2; public static final int LeftFace = 3; public static final int HALT = 4; public static final int[][] dirs = {{0,1},{1,0},{0,-1},{-1,0}}; // (line,column) TileMap tm; int nTile; int nNode; int[][] matrix; public FindCost(TileMap tm,int[] costs) { this.tm = tm; nTile = tm.width * tm.height; nNode = nTile * dirs.length; // そのタイルに来たときの顔の向きが4方向 matrix = new int[nNode][nNode]; if (debug) System.out.println("nTile="+nTile+", nNode="+nNode); for (int i=0; i 0) nRoute++; //System.err.println("nRoute="+nRoute); System.out.println(matrix.length+" "+nRoute); for (int i=0; i 0) System.out.println(i+" "+j+" "+matrix[i][j]); System.out.println(src+" "+dst); System.exit(1); } public int solve() { int src = tileface2index(linecolumn2tile(0,0),0); Dijkstra d = new Dijkstra(matrix,this); d.solve(src); int minlen = Integer.MAX_VALUE; int mindst= -1; for (int dir=0; dir len) { minlen = len; mindst = dst; } } if (minlen!=Integer.MAX_VALUE) doOutput(src,mindst); if (long_mode) { int[] path=d.getPath(mindst); StringBuffer sb=new StringBuffer(); for (int i=0; i "); } System.out.println(sb.toString()); } return minlen; } public String toString(int[][] m,int src,int dst) { int val = m[src][dst]; return (val == Integer.MAX_VALUE) ? "": index2string(src) + "-("+val+")->" + index2string(dst)+"\n"; } } static class Dijkstra { int nTown; int[][] map; int[] distance; int src; int[] via; FindCost fc; public Dijkstra(int[][] map,FindCost fc) { // コンストラクタ this.map = map; nTown = map.length; // 都市の数 this.fc = fc; } public void solve(int src) { this.src = src; // 始点を記憶しておく boolean[] fixed = new boolean[nTown]; // 最短距離が確定したかどうか distance = new int[nTown]; // 各都市までの最短距離 via = new int[nTown]; // その都市へ最短経路で到達する直前の都市 for (int i=0; i"+fc.index2string(marked)); for (int j=0; j=0 && !fixed[j]) { // 未確定なら // markedが表す都市を経由した距離を求める int newDistance = distance[marked]+map[marked][j]; // marked経由の距離が今までよりも小さければ更新する if (newDistance < distance[j]) { distance[j] = newDistance; via[j] = marked; // 直前の都市も記憶しておく } } } } } // まだ距離が確定していない都市の中で、もっとも近いものを探す int minIndex(int[] distance,boolean[] fixed) { int dist = Integer.MAX_VALUE; // 最短距離の初期値 int idx = -1; // 都市のIDの初期値 for (int i=0; i v = new Vector(); for (int i=dst; i != src; i=via[i]) { if (i == -1) return null; // srcからdstまでの経路が存在しない v.add(new Integer(i)); } v.add(new Integer(src)); // 始点も加える int[] route = new int[v.size()]; // 経路用の配列を用意して for (int i=0; i= height || col < 0 || col >= width); } public boolean isOutOfRange(int idx) { return (idx < 0 || idx >= map.length); } public int index2line(int idx) { return idx / width; } public int index2column(int idx) { return idx % width; } public int linecolumn2index(int line,int col) {return width*line+col;} public int get(int idx) { return (isOutOfRange(idx)) ? OUT_OF_RANGE: map[idx]; } public int get(int line,int col) { return (isOutOfRange(line,col)) ? OUT_OF_RANGE : get(linecolumn2index(line,col)); } public void set(int idx,int val) { if (!isOutOfRange(idx)) map[idx] = val; } public void set(int line,int col,int val) { if (!isOutOfRange(line,col)) set(linecolumn2index(line,col),val); } public String toString() { StringBuffer sb = new StringBuffer(); for (int line=0; line