解法一:Dijkstra+堆优化

真是艹了。题目没明确说是无向图,WA了还几次。用 BufferedReader.readLine() 读入,最大的那个测试点输入就直接超内存了。找了一种Java快速IO的写法重新处理了一下输入。

  1. import java.io.*;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.Comparator;
  5. import java.util.PriorityQueue;
  6. class Main {
  7. public static void main(String[] args) throws IOException {
  8. StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
  9. PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
  10. in.nextToken();
  11. final int N = (int) in.nval;
  12. in.nextToken();
  13. final int M = (int) in.nval;
  14. in.nextToken();
  15. final int src = (int) in.nval;
  16. in.nextToken();
  17. final int dst = (int) in.nval;
  18. Point[] points = new Point[N];
  19. for (int i = 0; i < N; ++i) {
  20. points[i] = new Point();
  21. }
  22. int[][][] graph = new int[2][N][N];
  23. for (int i = 0; i < 2; ++i) {
  24. for (int j = 0; j < N; ++j) {
  25. Arrays.fill(graph[i][j], 10000000);
  26. }
  27. }
  28. for (int i = 0, u, v, dis, cost; i < M; ++i) {
  29. in.nextToken();
  30. u = (int) in.nval;
  31. in.nextToken();
  32. v = (int) in.nval;
  33. in.nextToken();
  34. dis = (int) in.nval;
  35. in.nextToken();
  36. cost = (int) in.nval;
  37. graph[0][u][v] = dis;
  38. graph[1][u][v] = cost;
  39. graph[0][v][u] = dis;
  40. graph[1][v][u] = cost;
  41. }
  42. Comparator<Integer> comparator = new Comparator<Integer>() {
  43. @Override
  44. public int compare(Integer o1, Integer o2) {
  45. return points[o1].dis - points[o2].dis;
  46. }
  47. };
  48. PriorityQueue<Integer> heap = new PriorityQueue<>(comparator);
  49. points[src].dis = 0;
  50. heap.offer(src);
  51. int cnt = 0;
  52. int newDis, newCost;
  53. while (!heap.isEmpty()) {
  54. int start = heap.poll();
  55. if (points[start].isVisited) {
  56. continue;
  57. }
  58. points[start].isVisited = true;
  59. if (++cnt == N) {
  60. break;
  61. }
  62. for (int i = 0; i < N; ++i) {
  63. if (points[i].isVisited) {
  64. continue;
  65. }
  66. newDis = points[start].dis + graph[0][start][i];
  67. newCost = points[start].cost + graph[1][start][i];
  68. if ((newDis < points[i].dis) ||
  69. ((newDis == points[i].dis) && (newCost < points[i].cost))) {
  70. points[i].dis = newDis;
  71. points[i].cost = newCost;
  72. heap.offer(i);
  73. }
  74. }
  75. }
  76. out.println(points[dst].dis + " " + points[dst].cost);
  77. out.flush();
  78. }
  79. }
  80. class Point {
  81. int dis;
  82. int cost;
  83. boolean isVisited;
  84. Point() {
  85. dis = Integer.MAX_VALUE;
  86. cost = 0;
  87. isVisited = false;
  88. }
  89. }