一提起最短路,各位oier会想到什么呢?

floyd,spfa,dij,或是bellman-ford?

其实,只要学会一种算法,大部分最短路问题就能很快解决了。

他就是堆优化的dijkstra。

首先,先讲一下dij是怎么求最短路的。

Dijkstra是基于一种贪心的策略,首先用数组dis记录起点到每个结点的最短路径,再用一个数组保存已经找到最短路径的点

然后,从dis数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点记为已经找到最短路

此时完成一个顶点,再看这个点能否到达其它点(记为v),将dis[v]的值进行更新

不断重复上述动作,将所有的点都更新到最短路径

这种算法实际上是O(n^2)的时间复杂度,但我们发现在dis数组中选择最小值时,我们可以用一些数据结构来进行优化。

其实我们可以用STL里的堆来进行优化,堆相对于线段树以及平衡树有着常数小,码量小等优点,并且堆的一个妙妙的性质就是可以在nlogn的时限内满足堆顶是堆内元素的最大(小)值,之不正是我们要的嘛?

但是呢,dij处理不了负边,所以当题目出现负边时,dij就不能用了。

但反过来说,只要题目没负边,SPFA是一定会被卡的!

下面上代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define maxn 10005
  4. #define maxm 500005
  5. #define INF 1234567890
  6. inline int read()
  7. {
  8. int x=,k=; char c=getchar();
  9. while(c<''||c>''){if(c=='-')k=-;c=getchar();}
  10. while(c>=''&&c<='')x=(x<<)+(x<<)+(c^),c=getchar();
  11. return x*k;
  12. }
  13. struct Edge
  14. {
  15. int u,v,w,next;
  16. }e[maxm];
  17. int head[maxn],cnt,n,m,s,vis[maxn],dis[maxn];
  18. struct node
  19. {
  20. int w,now;
  21. inline bool operator <(const node &x)const
  22. //重载运算符把最小的元素放在堆顶(大根堆)
  23. {
  24. return w>x.w;//这里注意符号要为'>'
  25. }
  26. };
  27. priority_queue<node>q;
  28. //优先队列,其实这里一般使用一个pair,但为了方便理解所以用的结构体
  29. inline void add(int u,int v,int w)
  30. {
  31. e[++cnt].u=u;
  32. //这句话对于此题不需要,但在缩点之类的问题还是有用的
  33. e[cnt].v=v;
  34. e[cnt].w=w;
  35. e[cnt].next=head[u];
  36. //存储该点的下一条边
  37. head[u]=cnt;
  38. //更新目前该点的最后一条边(就是这一条边)
  39. }
  40. //链式前向星加边
  41. void dijkstra()
  42. {
  43. for(int i=;i<=n;i++)
  44. {
  45. dis[i]=INF;
  46. }
  47. dis[s]=;
  48. //赋初值
  49. q.push((node){,s});
  50. while(!q.empty())
  51. //堆为空即为所有点都更新
  52. {
  53. node x=q.top();
  54. q.pop();
  55. int u=x.now;
  56. //记录堆顶(堆内最小的边)并将其弹出
  57. if(vis[u]) continue;
  58. //没有遍历过才需要遍历
  59. vis[u]=;
  60. for(int i=head[u];i;i=e[i].next)
  61. //搜索堆顶所有连边
  62. {
  63. int v=e[i].v;
  64. if(dis[v]>dis[u]+e[i].w)
  65. {
  66. dis[v]=dis[u]+e[i].w;
  67. //松弛操作
  68. q.push((node){dis[v],v});
  69. //把新遍历到的点加入堆中
  70. }
  71. }
  72. }
  73. }
  74. int main()
  75. {
  76. n=read(),m=read(),s=read();
  77. for(int i=,x,y,z;i<=m;i++)
  78. {
  79. x=read(),y=read(),z=read();
  80. add(x,y,z);
  81. }
  82. dijkstra();
  83. for(int i=;i<=n;i++)
  84. {
  85. printf("%d ",dis[i]);
  86. }
  87. return ;
  88. }

谢谢大家!

c++最短路经典问题的更多相关文章

  1. POJ 2251 Dungeon Master(多层地图找最短路 经典bfs,6个方向)

    Dungeon Master Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 48380   Accepted: 18252 ...

  2. BZOJ_1001_狼抓兔子_(平面图求最小割+对偶图求最短路)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1001 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec   ...

  3. HDU 6071 Lazy Running (最短路)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6071 题解 又是一道虐信心的智商题... 首先有一个辅助问题,这道题转化了一波之后就会化成这个问题: ...

  4. ACM/ICPC 之 最短路径-dijkstra范例(ZOJ2750-POJ1135(ZOJ1298))

    最短路经典算法-dijkstra范例(两道),第一道是裸的dijkstra,第二道需要枚举所有边已找到可能的情况. ZOJ2750-Idiomatic Phrases Game 题意:见Code 题解 ...

  5. P3403 跳楼机

    题解: 据说是最短路经典题 考虑mod c一意义下 我们会发现mod c相同的话我们一定会用最少步数到达,剩余的都用c转移 由于转移图有环所以我们用spfa来dp(其实也可以理解成最短路) wa了好多 ...

  6. noip2017爆炸记——题解&总结&反省(普及组+提高组)

    相关链接: noip2018总结 noip2017是我见过的有史以来最坑爹的一场考试了. 今年北京市考点有一个是我们学校,我还恰好被分到了自己学校(还是自己天天上课的那个教室),于是我同时报了普及提高 ...

  7. 2019牛客暑期多校训练营(第四场)J-free

    >传送门< 题意:给你n个城市,m条道路,经过每一条要花费这条路的代价,现给你k个机会,使得最多k条路的代价为0,问从起点s到终点t花费的最少代价 思路:分层图最短路经典裸题 方法一 Co ...

  8. 图论:HDU2544-最短路(最全、最经典的最短路入门及小结)

    最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  9. UVA 10537 The Toll! Revisited 过路费(最短路,经典变形)

    题意:给一个无向图,要从起点s运送一批货物到达终点e,每个点代表城镇/乡村,经过城镇需要留下(num+19)/20的货物,而经过乡村只需要1货物即可.现在如果要让p货物到达e,那么从起点出发最少要准备 ...

随机推荐

  1. python3+ros+telnet+telnetlib

    利用python3的telnetlib模块 远程登录ros,输入帐号密码,然后执行命令,并导出结果到txt文本: 不过实际操作这种方式不行,因为telnet导出来的文本文件,带颜色编码,根本无法看哦. ...

  2. oracle里的统计信息

    1 oracle里的统计信息 Oracle的统计信息是这样的一组数据,存储在数据字典,从多个维度描述了oracle数据库对象的详细信息,有6种类型 表的统计信息:记录数.表块的数量.平均行长度等 索引 ...

  3. 转载:细说oracle 11g rac 的ip地址

    本文转载自:细说oracle 11g rac 的ip地址 http://blog.sina.com.cn/s/blog_4fe6d4250102v5fa.html 以前搭建oracle rac的时候( ...

  4. java成神之——接口,泛型,类

    接口 接口定义 默认方法 函数式接口 泛型 泛型类 泛型类继承 类型限定 泛型方法 泛型接口 类 构造函数 类的继承 抽象类 instanceof运算符 内部类 equals 结语 接口 接口定义 j ...

  5. 详解调试Apache的mod_rewrite模块

    大家都知道Apache里面的Rewrite规则是一件很蛋疼的事情,有时候只是想做一个伪静态而已,不想去研究那些复杂的规则,可官方给的规则又常常出错,出了问题我们就要调试一下,看看提交的参数被映射到了哪 ...

  6. Python生成器/推导式/生成器表达式

    一   生成器 生成器的本质就是迭代器 生成器的特点和迭代器一样,取值方式和迭代器一样(__next__(),  send():  给上一个yield传值) 生成器一般由生成器函数或者生成器表达式来创 ...

  7. C# RSA的加解密与签名验证

    最近做了一个CS架构的序列号生成器,用到 RSA加解密技术,以下是RSA的使用方法 RSA加密算法是一种非对称加密算法.在公钥加密标准和电子商业中RSA被广泛使用.RSA是1977年由罗纳德•李维斯特 ...

  8. VS2008与MATLAB R2007a混合编程配置过程

    系统平台:windows xp sp2, visual studio 2008 professional, matlab R2007a 首先,为了使matlab 能够找到vs2008编译器,需要下载以 ...

  9. iis7+的虚拟目录:未能加载程序集“**”。请确保在访问该页之前已经编译了此程序集

    在使用win8系统后,突然想运行iis,于是在windows组件中启用iis,并aspnet_regiis.exe -i注册iis后,于是开始发布了一个站点,一切正常 继而,在该站点下添加虚拟目录,然 ...

  10. RedHat&nbsp;Enterprise&nbsp;Linu…

    Abstract 在嵌入式开发中有宿主机和目标机之分:宿主机是执行编译.链接嵌入式软件的计算机:目标机是运行嵌入式软件的硬件平台. TFTP服务器作为工作于宿主机的软件,主要提供对目标机的主要映像文件 ...