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;
}
}
java dijkstra 单源 最短路径 优先队列 n趟
最新推荐文章于 2024-07-02 14:18:36 发布