package dijkstra; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.PriorityQueue; public class DijkstraDemo { public static int nNode; // 有nNode+1个节点, 从0到nNode号 public static ArrayList<ArrayList<Node>> vList; // 邻接表 public static int[] dist; public static int[] vist; public static int[] preId; public static void main(String[] args) { buildMap(); for(int i = 0; i <= nNode; i++){ System.out.println("\n####### 起点 = " + i + " #######"); // 起点为i dijkstra(i); // 起点为i到其他所有点的最短路径 ArrayList<ArrayList<Integer>> allPathFromOneNode = getAllPath(i); } } private static void buildMap() { // read data from file ArrayList<String> lines = new ArrayList<String>(); File file = new File("src/dijkstra/in.txt"); try { BufferedReader br = new BufferedReader(new FileReader(file)); while (br.ready()) { lines.add(br.readLine()); } br.close(); } catch (IOException e) { e.printStackTrace(); } // nNode = Integer.parseInt(lines.get(0).trim()); initSize(); for (int i = 2; i < lines.size(); i++) { String[] strs = lines.get(i).trim().split(" "); addNodeUndirected(Integer.parseInt(strs[0]), Integer.parseInt(strs[1]), Integer.parseInt(strs[2])); } // addNodeUndirected(1, 2, 5); // addNodeUndirected(1, 3, 7); // addNodeUndirected(2, 3, 1); // addNodeUndirected(2, 4, 10); // addNodeUndirected(3, 4, 1); // addNodeUndirected(3, 5, 2); // addNodeUndirected(4, 5, 3); System.out.println("buildMap finised..."); } private static void initSize() { vList = new ArrayList<ArrayList<Node>>(); for (int i = 0; i <= nNode; i++) { vList.add(new ArrayList<Node>()); } dist = new int[nNode + 1]; vist = new int[nNode + 1]; preId = new int[nNode + 1]; } private static void dijkstra(int startId) { // init data for (int i = 0; i <= nNode; i++) { dist[i] = Integer.MAX_VALUE; vist[i] = 0; preId[i] = i; } // add start Node PriorityQueue<Node> myQueue = new PriorityQueue<Node>(); Node start = new Node(startId, 0); dist[startId] = 0; preId[startId] = startId; myQueue.add(start); // go while (!myQueue.isEmpty()) { Node cNode = myQueue.poll(); if (vist[cNode.id] == 1) continue; vist[cNode.id] = 1; int len = vList.get(cNode.id).size(); for (int i = 0; i < len; i++) { Node nextNode = vList.get(cNode.id).get(i); int nextNodeDistFromStart = dist[cNode.id] + nextNode.distPre; if (nextNodeDistFromStart < dist[nextNode.id]) { dist[nextNode.id] = nextNodeDistFromStart; // nextNode.distPre = dist[nextNode.id]; // 不能修改原始点, 如果要求多次Dijkstra Node nextNode2 = new Node(nextNode.id, dist[nextNode.id]); preId[nextNode.id] = cNode.id; myQueue.add(nextNode2); } } } System.out.println("dijkstra finised..."); } private static ArrayList<ArrayList<Integer>> getAllPath(int startId) { ArrayList<ArrayList<Integer>> allPathFromOneNode = new ArrayList<ArrayList<Integer>>(); for (int i = 0; i <= nNode; i++) { System.out.println("dist(" + startId + "->" + i + ") = " + dist[i]); ArrayList<Integer> path = getPath(startId, i); allPathFromOneNode.add(path); // show the path from strat node to ith node int flag = 0; for (Integer id : path) { if (flag > 0) { System.out.print(" -> "); } System.out.print(id); flag = 1; } System.out.println(); } System.out.println("getAllPath finised..."); return allPathFromOneNode; } private static ArrayList<Integer> getPath(int startId, int cId) { ArrayList<Integer> path = new ArrayList<Integer>(); ArrayList<Integer> rePath = new ArrayList<Integer>(); if (dist[cId] == Integer.MAX_VALUE) return path; while (preId[cId] != cId) { rePath.add(cId); cId = preId[cId]; } rePath.add(cId); for (int i = rePath.size() - 1; i >= 0; i--) { path.add(rePath.get(i)); } return path; } private static void addNodeUndirected(int x, int y, int w) { Node nodeXY = new Node(y, w); Node nodeYX = new Node(x, w); vList.get(x).add(nodeXY); vList.get(y).add(nodeYX); } private static void addNodeDirected(int x, int y, int w) { Node nodeXY = new Node(y, w); vList.get(x).add(nodeXY); } private static void showPreId() { for (int i = 0; i <= nNode; i++) { System.out.println(preId[i]); } } } class Node implements Comparable<Object> { int id; int distPre; // the distance from id Node to pre node or start Node public Node(int id, int dist) { this.id = id; this.distPre = dist; } @Override public int compareTo(Object o) { Node other = (Node) o; if (this.distPre > other.distPre) { return 1; } else if (this.distPre < other.distPre) { return -1; } return 0; } }