[关闭]
@ZCDHJ 2018-09-25T09:10:28.000000Z 字数 1501 阅读 536

51Nod1443 路径和树

最短路径


51Nod

要建出一棵最短路树,先跑一边最短路,然后枚举找一下每个点的最短路是由哪一个点松弛过来的,然后就可以求出来了。

那么要求权值和最小的最短路树,一种暴力的想法是将 最短路图 求出来,再跑一遍 mst。但是可以发现,每个点的选择是互相独立的,所以只要记一下松弛过来的父边权值最小的边就可以了。

注意开long long

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <queue>
  5. typedef long long LL;
  6. #define int LL
  7. const int INF = 0x7f7f7f7f;
  8. const int MAXN = 3e5;
  9. const int MAXM = 3e5;
  10. int n, m, s, edge, ans;
  11. int firstEdge[MAXN + 5], minF[MAXN + 5], dist[MAXN + 5];
  12. struct Edge {
  13. int to, w, nxt;
  14. Edge(){}
  15. Edge(int x, int y, int z) {
  16. to = y;
  17. w = z;
  18. nxt = firstEdge[x];
  19. }
  20. } e[MAXM * 2 + 5];
  21. struct Heap {
  22. int x, y;
  23. Heap(){}
  24. Heap(int a, int b) {
  25. x = a;
  26. y = b;
  27. }
  28. };
  29. bool operator < (const Heap &a, const Heap &b) {
  30. return a.y > b.y;
  31. }
  32. std::priority_queue <Heap> q;
  33. inline int read() {
  34. register int x = 0;
  35. register char ch = getchar();
  36. while(!isdigit(ch)) ch = getchar();
  37. while(isdigit(ch)) {
  38. x = x * 10 + ch - '0';
  39. ch = getchar();
  40. }
  41. return x;
  42. }
  43. inline void addEdge(int x, int y, int z) {
  44. e[++edge] = Edge(x, y, z);
  45. firstEdge[x] = edge;
  46. }
  47. void Dijkstra() {
  48. memset(dist, INF, sizeof(dist));
  49. dist[s] = 0;
  50. q.push(Heap(s, 0));
  51. while(!q.empty()) {
  52. Heap from = q.top();
  53. q.pop();
  54. if(from.y != dist[from.x]) continue;
  55. for(int k = firstEdge[from.x]; k; k = e[k].nxt) {
  56. int to = e[k].to, w = e[k].w;
  57. if(dist[to] > dist[from.x] + w) {
  58. dist[to] = dist[from.x] + w;
  59. q.push(Heap(to, dist[to]));
  60. }
  61. }
  62. }
  63. }
  64. signed main() {
  65. n = read();
  66. m = read();
  67. for(int i = 1; i <= m; ++i) {
  68. int a = read(), b = read(), c = read();
  69. addEdge(a, b, c);
  70. addEdge(b, a, c);
  71. }
  72. s = read();
  73. Dijkstra();
  74. memset(minF, INF, sizeof(minF));
  75. minF[s] = 0;
  76. for(int i = 1; i <= n; ++i) {
  77. for(int k = firstEdge[i]; k; k = e[k].nxt) {
  78. int to = e[k].to, w = e[k].w;
  79. if(dist[to] == dist[i] + w) minF[to] = std::min(minF[to], w);
  80. }
  81. }
  82. for(int i = 1; i <= n; ++i) ans += minF[i];
  83. printf("%lld\n", ans);
  84. return 0;
  85. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注