c++最短路经典问题
一提起最短路,各位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++最短路经典问题的更多相关文章
- POJ 2251 Dungeon Master(多层地图找最短路 经典bfs,6个方向)
Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 48380 Accepted: 18252 ...
- BZOJ_1001_狼抓兔子_(平面图求最小割+对偶图求最短路)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1001 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec ...
- HDU 6071 Lazy Running (最短路)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6071 题解 又是一道虐信心的智商题... 首先有一个辅助问题,这道题转化了一波之后就会化成这个问题: ...
- ACM/ICPC 之 最短路径-dijkstra范例(ZOJ2750-POJ1135(ZOJ1298))
最短路经典算法-dijkstra范例(两道),第一道是裸的dijkstra,第二道需要枚举所有边已找到可能的情况. ZOJ2750-Idiomatic Phrases Game 题意:见Code 题解 ...
- P3403 跳楼机
题解: 据说是最短路经典题 考虑mod c一意义下 我们会发现mod c相同的话我们一定会用最少步数到达,剩余的都用c转移 由于转移图有环所以我们用spfa来dp(其实也可以理解成最短路) wa了好多 ...
- noip2017爆炸记——题解&总结&反省(普及组+提高组)
相关链接: noip2018总结 noip2017是我见过的有史以来最坑爹的一场考试了. 今年北京市考点有一个是我们学校,我还恰好被分到了自己学校(还是自己天天上课的那个教室),于是我同时报了普及提高 ...
- 2019牛客暑期多校训练营(第四场)J-free
>传送门< 题意:给你n个城市,m条道路,经过每一条要花费这条路的代价,现给你k个机会,使得最多k条路的代价为0,问从起点s到终点t花费的最少代价 思路:分层图最短路经典裸题 方法一 Co ...
- 图论:HDU2544-最短路(最全、最经典的最短路入门及小结)
最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- UVA 10537 The Toll! Revisited 过路费(最短路,经典变形)
题意:给一个无向图,要从起点s运送一批货物到达终点e,每个点代表城镇/乡村,经过城镇需要留下(num+19)/20的货物,而经过乡村只需要1货物即可.现在如果要让p货物到达e,那么从起点出发最少要准备 ...
随机推荐
- float型数据与字节数组的转化
float型数据与字节数组的转化 字节(float)浮点数为例. 一.C语言 转化常见的方法有: 1.强制指针类型转换. [html] view plain copy //转换float数据到字节数组 ...
- 讲解一下this (作用域)
this的指向:普通函数内的this指向全局变量 构造函数内部this指向新创建出来的对象 对象方法内的this指向的是调用该方法的对象 call,apply,bind可以改变this的指向
- Flask之测试与部署
5.1 蓝图Blueprint 为什么学习蓝图? 我们学习Flask框架,是从写单个文件,执行hello world开始的.我们在这单个文件中可以定义路由.视图函数.定义模型等等.但这显然存在一个问题 ...
- Python中的闭包与迭代器
前面内容补充 函数名分应用(第一类对象) 函数名的命名规范与变量命名是一样的函数名其实就是变量名 函数名可以作为列表中的元素进行存储 例如: def func1(): pass def func2() ...
- MFC 打开外部EXE文件的三种方法
目前知道三种方式:WinExec,ShellExecute ,CreateProcess,别人已经总结的很好了<vc中调用其他应用程序的方法(函数) winexec,shellexecute , ...
- centos6下的安装navicat premium
centos6下的安装navicat premium CentOS6下做开发的时候,数据库客户端是一个必须要有的工具,因为经常要和数据库打交道.由于数据库的类型多样,有MySQL.Oracle.Pos ...
- spring注解注入属性
- 管理授权&管理决策&管理组织&管理目标
[管理授权] 1.如果一个管理者不明白为公司培养人的责任,就很可能成为公司的瓶颈.这个问题的解决在于让管理者学会“授权”,把大部分自己紧抓不放的事情下放给部门内其他人做. 2.为一件事负责和亲自做是两 ...
- 安装 Windows Service
1.打开 VS 命令行窗口 2. installutil /u service文件路径 (卸载原有服务) 3, installutil /i service 文件路径 (安装服务)
- cocos+kbe问题记录
1.不要使用setTimeout函数 setTimeout函数,setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. 是HTML DOM中的方法,在游戏中使用,属于全局的延时,当游 ...