问题描述
求从 开始的所有点的最短路径的长度s
。点 id 是从 1, 2, ... 到 N。
输入
- N, M, S
- 后面是 M 行,每一行是
u v w
,代表一条从u
到到v
长度为 的路径w
。
输出
- N行,每一行是s到第i个点的距离。如果无法到达,则目的地为 -1。
-
尺寸
- N <= 1,000,000
- M <= 2,000,000
- w >= 0
- 总长度以 为界
int32_t
难点:
时间限制:
1.5s
内存限制: 200M
为了保证空间复杂度,这里选用List<Node>[]来存储图的信息,其中node节点记录pos位置和cost目标点到pos位置的花费,数据的读取采用BufferedReader而不是Scanner,亲测,效率更高;将数据存储好之后采用Dijkstra算法(参考百度百科)求得目标点到其余每个点的最短距离。代码如下:
public class Temp { static int[] dist = new int[1000000]; public static void main(String[] args) throws IOException { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); int num[] = toInteger(bufferedReader.readLine()); int N = num[0],M=num[1],S=num[2]; List<Node>[] list = new ArrayList[N]; for (int i=0;i<N;i++){ list[i] = new ArrayList<>(); } Arrays.fill(dist,0,N,-1); while (M>0){ num = toInteger(bufferedReader.readLine()); int start = num[0] -1,end = num[1] - 1,length = num[2]; Node node = new Node(end,length); List<Node> map = list[start]; map.add(node); --M; } Dijkstra(S - 1, list, new int[N]); for (int i=0;i<list.length;i++) { // int res = Dijkstra(S - 1, i, list, new int[N]); System.out.println(dist[i]); } } //visit[i] == 0,代表未访问,visit[0] == -1代表已访问 public static int Dijkstra(int src, List<Node>[] graph, int[] visit){ PriorityQueue<Node> pq = new PriorityQueue<>(new Node()); //将起点加入pq pq.add(new Node(src, 0)); while (!pq.isEmpty()){ Node t = pq.poll(); if (dist[t.node] > t.cost || dist[t.node] < 0) { dist[t.node] = t.cost; } //t节点表示还未访问 if (visit[t.node]==0){ //将节点设置为已访问 visit[t.node] = -1; //将当前节点相连且未访问的节点遍历 List<Node> nodes = graph[t.node]; for (Node k : nodes){ if (visit[k.node] == 0 ){ k.setCost(k.getCost()+t.cost); pq.add(k); } } } } return -1; } //定义一个存储节点和离起点相应距离的数据结构 static class Node implements Comparator<Node> { public int node; public int cost; public Node(){} public Node(int node, int cost){ this.node = node; this.cost = cost; } public int getNode() { return node; } public void setNode(int node) { this.node = node; } public int getCost() { return cost; } public void setCost(int cost) { this.cost = cost; } @Override public int compare(Node node1, Node node2){ return node1.cost-node2.cost; } } private static int[] toInteger(String srt) { int i = 0; int a1 = 0; int a2 = 0; int a3 = 0; while (srt.charAt(i)!=' ') { a1 = a1 * 10 + (srt.charAt(i) - '0'); i++; } i++; while (srt.charAt(i)!=' ') { a2 = a2 * 10 + (srt.charAt(i) - '0'); i++; } i++; while (i != srt.length()) { a3 = a3 * 10 + (srt.charAt(i) - '0'); i++; } int[] list = new int[3]; list[0] = a1; list[1] = a2; list[2] = a3; return list; } }