1. #define _CRT_SECURE_NO_WARNINGS
  2. /*
  3. 7 10
  4. 0 1 5
  5. 0 2 2
  6. 1 2 4
  7. 1 3 2
  8. 2 3 6
  9. 2 4 10
  10. 3 5 1
  11. 4 5 3
  12. 4 6 5
  13. 5 6 9
  14. 6
  15. */
  16. #include <iostream>
  17. #include <vector>
  18. #include <algorithm>
  19. #include <cstdio>
  20. using namespace std;
  21. const int maxn = + ;
  22. const int INF = ;
  23. int cost[maxn][maxn]; //表示边e=(u,v)的权值 (不存在这条边时设为INF)
  24. int d[maxn]; //顶点出发的最短距离
  25. bool used[maxn]; //已经使用过的图
  26. int V, E;
  27. void init();
  28. void dijkstra(int s);
  29. void input();
  30. void init()
  31. {
  32. for (int i = ; i < V; i++) {
  33. for (int j = ; j < V; j++) {
  34. if (i == j) {
  35. cost[i][j] = ;
  36. }
  37. else {
  38. cost[i][j] = INF;
  39. }
  40. }
  41. }
  42. }
  43. void dijkstra(int s)
  44. {
  45. fill(d, d + V, INF);
  46. fill(used, used + V, false);
  47. d[s] = ;
  48. while (true) {
  49. int v = -;
  50. //从尚未使用过的顶点中选择一个距离最小的顶点
  51. for (int u = ; u < V; u++) {
  52. if (!used[u] && (v == - || d[u] < d[v])) {
  53. v = u;
  54. }
  55. }
  56. if (v == -) break; //已经没有尚未使用的点了
  57. used[v] = true; //标志v已访问
  58. for (int u = ; u < V; u++) {
  59. d[u] = min(d[u], d[v] + cost[u][v]);
  60. }
  61. }
  62. }
  63. void input()
  64. {
  65. int s, t, ct;
  66. for (int i = ; i < E; i++)
  67. {
  68. cin >> s >> t >> ct;
  69. cost[s][t] = cost[t][s] = ct;
  70. }
  71. }
  72. int main()
  73. {
  74. cin >> V >> E; //输入顶点数和边数
  75. init(); //必须要初始化
  76. input(); //输入临接的边和权值
  77. dijkstra(); //设置起点
  78. int ov;
  79. cin >> ov; //输入终点
  80. cout << d[ov] << endl;
  81. return ;
  82. }

//解法二:

需要优化的是数值的插入(更新)和取出最小值两个操作,因此使用堆就可以了。把每个顶点当前的最短距离用堆维护,在更新最短距离时,把对应的元素往根的方向移动以满足堆的性质。而每次从堆中取出的最小值就是下一次要使用的顶点。这样堆中元素共有O(|V|)个。更新和取出数值的操作有O(|E|)次,因此整个算法复杂度是O(|E|log|V|)。

下面是使用STL的priority_queue的实现。在每次更新时往堆里插入当前最短距离和顶点的值对。插入的次数是O(|E|)次,因此元素也是O(|E|)个。当取的最小值不是最短距离的话,就丢弃这个值。

  1. #define _CRT_SECURE_NO_WARNINGS
  2. /*
  3. 7 10
  4. 0 1 5
  5. 0 2 2
  6. 1 2 4
  7. 1 3 2
  8. 2 3 6
  9. 2 4 10
  10. 3 5 1
  11. 4 5 3
  12. 4 6 5
  13. 5 6 9
  14. 6
  15. */
  16. #include <iostream>
  17. #include <vector>
  18. #include <utility>
  19. #include <queue>
  20. #include <functional>
  21. #include <algorithm>
  22. #include <cstdio>
  23. using namespace std;
  24. const int maxn = + ;
  25. const int INF = ;
  26. struct edge
  27. {
  28. int to, cost;
  29. };
  30. typedef pair<int, int> P; //first是最短距离,second是顶点的编号
  31. int V, E;
  32. vector<edge> G[maxn];
  33. int d[maxn];
  34. //void init();
  35. void input();
  36. void dijkstra(int s)
  37. {
  38. //通过指定greater<P>参数,堆按照first从小到大的顺序取出值
  39. priority_queue<P, vector<P>, greater<P> > que;
  40. fill(d, d + V, INF);
  41. d[s] = ;
  42. que.push(P(, s));
  43. while (!que.empty()) {
  44. P p = que.top(); que.pop();
  45. int v = p.second;
  46. if (d[v] < p.first) continue;
  47. for (int i = ; i < G[v].size(); i++) {
  48. edge e = G[v][i];
  49. if (d[e.to] > d[v] + e.cost) {
  50. d[e.to] = d[v] + e.cost;
  51. que.push(P(d[e.to], e.to));
  52. }
  53. }
  54. }
  55. }
  56. //void init()
  57. //{
  58. //}
  59. void input()
  60. {
  61. int s, t, ct;
  62. edge tmp;
  63. for (int i = ; i < E; i++) {
  64. cin >> s >> t >> ct;
  65. tmp.to = t; tmp.cost = ct;
  66. G[s].push_back(tmp);
  67. //无向图,反向也需要连接
  68. tmp.to = s; tmp.cost = ct;
  69. G[t].push_back(tmp);
  70. }
  71. }
  72. int main()
  73. {
  74. cin >> V >> E;
  75. //init();
  76. input();
  77. dijkstra();
  78. int ov;
  79. cin >> ov;
  80. cout << d[ov] << endl;
  81. return ;
  82. }

单源最短路径问题(dijkstra算法 及其 优化算法(优先队列实现))的更多相关文章

  1. 单源最短路径(dijkstra算法)php实现

    做一个医学项目,当中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路例如以下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么( ...

  2. 单源最短路径:Dijkstra算法(堆优化)

    前言:趁着对Dijkstra还有点印象,赶快写一篇笔记. 注意:本文章面向已有Dijkstra算法基础的童鞋. 简介 单源最短路径,在我的理解里就是求从一个源点(起点)到其它点的最短路径的长度. 当然 ...

  3. 0016:单源最短路径(dijkstra算法)

    题目链接:https://www.luogu.com.cn/problem/P4779 题目描述:给定一个 n 个点,m 条有向边的带非负权图,计算从 s 出发,到每个点的距离. 这道题就是一个单源最 ...

  4. 【算法导论】单源最短路径之Dijkstra算法

    Dijkstra算法解决了有向图上带正权值的单源最短路径问题,其运行时间要比Bellman-Ford算法低,但适用范围比Bellman-Ford算法窄. 迪杰斯特拉提出的按路径长度递增次序来产生源点到 ...

  5. 单源最短路径问题-Dijkstra算法

    同样是层序遍历,在每次迭代中挑出最小的设置为已知 ===================================== 2017年9月18日10:00:03 dijkstra并不是完全的层序遍历 ...

  6. 单源最短路径(3):SPFA 算法

    SPFA(Shortest Path Faster Algorithm)算法,是西南交通大学段凡丁于 1994 年发表的,其在 Bellman-ford 算法的基础上加上一个队列优化,减少了冗余的松弛 ...

  7. 【模板】单源最短路径(Dijkstra)/洛谷P4779

    题目链接 https://www.luogu.com.cn/problem/P4779 题目大意 给定一个 \(n\) 个点 \(m\) 条边有向图,每个点有一个非负权值,求从 \(s\) 点出发,到 ...

  8. [模板]单源最短路径(Dijkstra)

    如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 主要还是再打一遍最短路,这种算法我用的不多... #include<bits/stdc++.h> using namesp ...

  9. Dijkstra算法解决单源最短路径

    单源最短路径问题:给定一个带权有向图 G = (V, E), 其中每条边的权是一个实数.另外,还给定 V 中的一个顶点,称为源.现在要计算从源到其他所有各顶点的最短路径长度.这里的长度是指路上各边权之 ...

随机推荐

  1. Windows10下Docker监控管理工具:Hyper-V管理器

    用Hyper-V管理器监控管理Docker,看到最新的MobyLinuxVM了. 今天启动Docker,出现内存不足的问题,调节内存配置即可.

  2. Vue 组件化

    根实例└─ TodoList ├─ TodoItem │ ├─ DeleteTodoButton │ └─ EditTodoButton └─ TodoListFooter ├─ ClearTodos ...

  3. React child

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  4. FICO基础知识(三)

    成本中心: 成本中心是企业内的最小职责单位,是每一笔费用的具体接收者.创建成本中心主数据时必须将每个成本中心分配给标准层次结构的某个节点,标准层次结构反映了成本中心与成本中心.成本中心与成本中心组.成 ...

  5. 操作系统+编程语言的分类+执行python程序的两种方式+变量

    1.什么是操作系统? 操作系统就是一个协调\管理\控制计算机硬件资源与软件资源的一个控制程序. 2.为何要操作系统? a.把复杂的硬件操作封装成简单的功能\接口用来给用户或者程序来使用(文件) b.把 ...

  6. indicator function指示函数

    指示函数   在集合论中,指示函数是定义在某集合X上的函数,表示其中有哪些元素属于某一子集A. 中文名 指示函数 外文名 indicator function 相关学科 数学.组合数学 其他称呼 特征 ...

  7. mysql关于binlog日志的操作

    查看binlog日志选项和存储位置: mysql> show variables like 'log_%'; 1.查看所有binlog日志列表 mysql> show master log ...

  8. Inside JVM 内存模型

    Inside JVM 内存模型 来源  原文:https://blog.csdn.net/silentbalanceyh/article/details/4661230 参考:IBM开发中心文档,&l ...

  9. 【刷题】LOJ 2863 「IOI2018」组合动作

    题目描述 你在玩一个动作游戏.游戏控制器有 \(4\) 个按键,A.B.X 和 Y.在游戏中,你用组合动作来赚金币.你可以依次按这些按键来完成一个组合动作. 这个游戏有一个隐藏的按键序列,可以表示为由 ...

  10. BZOJ 4556: [Tjoi2016&Heoi2016]字符串(后缀数组 + 二分答案 + 主席树 + ST表 or 后缀数组 + 暴力)

    题意 一个长为 \(n\) 的字符串 \(s\),和 \(m\) 个询问.每次询问有 \(4\) 个参数分别为 \(a,b,c,d\). 要你告诉它 \(s[a...b]\) 中的所有子串 和 \(s ...