// this version illustrates use of Dijkstra's shortest-path algorithm // and uses my own DTree priority queue, in-line import java.util.Scanner; class City4 { // main procedure public static void main (String Scanner[]) { Scanner inScan = new Scanner (System.in); int n; // number of rows, columns int start; int destination; final int N; // number of nodes // read in the problem n = inScan.nextInt (); N = n * n - 1; start = inScan.nextInt (); destination = inScan.nextInt (); System.out.println("start = " + start + " Destination = " + destination); // create the neighbor structure int[][] neighbor = new int[N+1][2]; for (int i = 0; i < N; i++) for (int j = 0; j < 2; j++) neighbor[i][j] = -1; for (int x = 0; x < N; x++) { // as stated: switch (x % n) { switch (x % 4) { case 0: if (x-n >= 0) neighbor[x][0] = x-n; // north if (x+n < N) neighbor[x][1] = x+n; // south break; case 1: if ((x-n >= 0) && (x % n < n-1)) neighbor[x][0] = x-n+1; // ne if ((x+n < N) && (x % n > 0)) neighbor[x][1] = x+n-1; // sw break; case 2: if (x % n > 0) neighbor[x][0] = x-1; // west if (x % n < n-1) neighbor[x][1] = x+1; // east break; case 3: if ((x-n > 0) && (x % n > 0)) neighbor[x][0] = x-n-1; // nw if ((x+n < N) && (x % n < n-1)) neighbor[x][1] = x+n+1; // se } } // create the distance array final int[] d = new int[N+1]; for (int i = 0; i < N; i++) d[i] = Integer.MAX_VALUE; d[start] = 0; d[N] = Integer.MAX_VALUE; // create the set of settled nodes boolean[] settled = new boolean[N+1]; for (int i = 0; i < N; i++) settled[i] = false; // create the path int[] path = new int[N+1]; for (int i = 0; i < N; i++) path[i] = -1; // find shortest path using Dijkstra's algorithm // priority queue class PriorityQueue { private int q [] = new int[2*N+1]; public PriorityQueue () { q = new int[2*N+1]; for (int i = 1; i < q.length; i++) { q[i] = N; } } public void add (int x) { int L = x + N + 1; for (;;) { q[L] = x; if (L == 1) break; L = L / 2 ; if (d[q[L]] <= d[x]) break; } } public int poll () { int result = q[1]; int L = result + N + 1; int m = N; int n, p; for (;;) { q[L] = m; if (L == 1) break; p = L / 2; // L's parent n = q[4 * p - L + 1]; // L's sibling if (d[n] < d[m]) m = n; L = p; } return result; } public int min () { return q[1]; } public boolean isEmpty() { return q[1] == N; } } PriorityQueue q = new PriorityQueue(); // put all the nodes into the queue q.add(start); while (! q.isEmpty()) { int x = q.poll(); // extracts minimum if (x == destination) break; settled[x] = true; // System.out.println("d[" + x + "] = " + d[x]); // "relax" neighbors for (int i = 0; i < 2; i++) { int y = neighbor[x][i]; // for each vertex y adjacent to x, not in s if ((y != -1) && (! settled[y]) && (d[y] > d[x] + 1)) { d[y] = d[x] + 1; path[y] = x; q.add (y); } } } if (d[destination] == Integer.MAX_VALUE) System.out.println("no path!"); else { System.out.println("distance = " + d[destination]); // find a path of minimum length System.out.print("Output: "); // reverse path int x = destination; int px = path[x]; while (x != start) { int ppx = path[px]; path[px] = x; x = px; px = ppx; } // now print it out x = start; while (x != destination) { System.out.print(x + " "); x = path[x]; } System.out.println(x); } } }