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,那么从起点出发最少要准备 ...
随机推荐
- python开发面向对象基础:组合&继承
一,组合 组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合 人类装备了武器类就是组合 1.圆环,将圆类实例后传给圆环类 #!/usr/bin/env python #_*_ ...
- 从零开始搭建包含多个子系统的Vue工程项目
本文以windows为例,介绍支持多个子系统的Vue工程项目的搭建过程,相对于单一系统的工程,多个子系统引入了如下一些问题: 项目目录结构设计 打包结果设计:每个子系统可以独立发布上线 多布局实现:多 ...
- CSS滤镜模糊效果
.blur { -webkit-filter: blur(6px); -moz-filter: blur(6px); -ms-filter: blur(6px); filter: blur(6px); ...
- Python多线程-生产者消费者模型
用多线程和队列来实现生产者消费者模型 # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import threading imp ...
- day3心得
1. 集合 主要作用: 去重 关系测试, 交集\差集\并集\反向(对称)差集 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 >>&g ...
- Android Studio 配置模拟器AVD存放路径(默认在c盘,解决c盘空间不够问题)
Android Studio 安装之后,默认的会给我们创建一个 Nexus 的模拟器, 这个模拟器的镜像文件放在了 C:\Users\Administrator\.android 中 其中的avd文 ...
- ASP.NET Core应用到Windows Service中
托管到Windows Service中 众所周知,ASP.NET Core采用了和传统ASP.NET不同的托管和HTTP处理方式,即把服务器和托管环境完全解耦. ASP.NET Core内置了两个HT ...
- List扩展方法汇总(仅备注)
不管在c/s还是b/s的c#语言开发程序中,经常会用到List的扩展方法,尤其在json格式的数据和服务端交互越来越流行,很多时候总是在开发使用到的时候才去搜索有些扩展方法或者linq的用法,在这里, ...
- Bypassing iPhone Code Signatures
[Bypassing iPhone Code Signatures] Starting with the recent beta releases of the iPhoneOS, Apple has ...
- 05-nginx定时任务完成日志切割
目标:每天晚上凌晨一点钟左右把昨天的任务给它切掉,把昨天的日志给它改个名存起来,根据昨天的时间给它改个名存起来,所以要根据日期生成文件名. 也许你不会写bash脚本,但是老师带着你一步一步地来. sh ...