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

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

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

他就是堆优化的dijkstra。

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

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

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

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

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

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

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

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

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

下面上代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
#define maxm 500005
#define INF 1234567890
inline int read()
{
int x=,k=; char c=getchar();
while(c<''||c>''){if(c=='-')k=-;c=getchar();}
while(c>=''&&c<='')x=(x<<)+(x<<)+(c^),c=getchar();
return x*k;
}
struct Edge
{
int u,v,w,next;
}e[maxm];
int head[maxn],cnt,n,m,s,vis[maxn],dis[maxn];
struct node
{
int w,now;
inline bool operator <(const node &x)const
//重载运算符把最小的元素放在堆顶(大根堆)
{
return w>x.w;//这里注意符号要为'>'
}
};
priority_queue<node>q;
//优先队列,其实这里一般使用一个pair,但为了方便理解所以用的结构体
inline void add(int u,int v,int w)
{
e[++cnt].u=u;
//这句话对于此题不需要,但在缩点之类的问题还是有用的
e[cnt].v=v;
e[cnt].w=w;
e[cnt].next=head[u];
//存储该点的下一条边
head[u]=cnt;
//更新目前该点的最后一条边(就是这一条边)
}
//链式前向星加边
void dijkstra()
{
for(int i=;i<=n;i++)
{
dis[i]=INF;
}
dis[s]=;
//赋初值
q.push((node){,s});
while(!q.empty())
//堆为空即为所有点都更新
{
node x=q.top();
q.pop();
int u=x.now;
//记录堆顶(堆内最小的边)并将其弹出
if(vis[u]) continue;
//没有遍历过才需要遍历
vis[u]=;
for(int i=head[u];i;i=e[i].next)
//搜索堆顶所有连边
{
int v=e[i].v;
if(dis[v]>dis[u]+e[i].w)
{
dis[v]=dis[u]+e[i].w;
//松弛操作
q.push((node){dis[v],v});
//把新遍历到的点加入堆中
}
}
}
}
int main()
{
n=read(),m=read(),s=read();
for(int i=,x,y,z;i<=m;i++)
{
x=read(),y=read(),z=read();
add(x,y,z);
}
dijkstra();
for(int i=;i<=n;i++)
{
printf("%d ",dis[i]);
}
return ;
}

谢谢大家!

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. windows抓包工具Wireshark(过滤)

    1.IP过滤 ip.src ==192.168.0.208(ip.src eq 192.168.0.208) //来源等于某个ip ip.dst ==192.168.0.208(ip.dst eq 1 ...

  2. 普及组2008NOIP 排座椅(贪心+排序)

    排座椅 时间限制: 1 Sec  内存限制: 50 MB提交: 4  解决: 3[提交][状态][讨论版][命题人:外部导入] 题目描述 上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任 ...

  3. CentOS yum 安装RabbitMQ

    最近在做机器学习的任务系统,任务模块使用了消息对联,比较快速的搭建方法: 1.安装erlang 下载rpm仓库:wget http://packages.erlang-solutions.com/er ...

  4. Python多线程-事件

    线程事件用于线程控制线程,实现多个进程间的交互,线程事件的初始值为False set:将线程事件的值设为True clear:将线程事件的值设为False # -*- coding:utf-8 -*- ...

  5. Kali下Ahmyth的使用

    项目地址:https://github.com/AhMyth/AhMyth-Android-RAT 下载后打开 安装nodejs,nodejs在官网下载,下载完后解压,切到bin目录下 设置全局 ro ...

  6. java成神之——Fork/Join基本使用

    Fork/Join 大任务分小任务,小任务结果合并 ForkJoinPool pool = new ForkJoinPool(); RecursiveTask<Integer> task1 ...

  7. CNN感受野计算

    无痛理解CNN中的感受野receptive field CNN中感受野的计算 从直观上讲,感受野就是视觉感受区域的大小.在卷积神经网络中,感受野的定义是决定某一层输出结果中一个元素所对应的输入层的区域 ...

  8. Android 从本地图库或拍照后裁剪图片并设置头像

    在QQ和微信等应用都会有设置头像,一般都是从本地图库选取或相机拍照,然后再截图自己喜欢的部分,然后设置.最后一步把截取好的图片再保存到本地,来保存头像.为了大家使用方便,我把自己完整的代码贴出来,大家 ...

  9. Mycat实战之主键数据库自增方式

    创建一个 person表,主键为Id,hash方式分片,主键自增(采用数据库方式) #person表结构如下 Id,主键,Mycat自增主键 name,字符串,16字节最长 school,毕业学校,数 ...

  10. 实例解说Linux命令行uniq

    Linux命令uniq的作用是过滤重复部分显示文件内容,这个命令读取输入文件,并比较相邻的行.在正常情况下,第二个及以后更多个重复行将被删去,行比较是根据所用字符集的排序序列进行的.该命令加工后的结果 ...