0016:单源最短路径(dijkstra算法)
题目链接:https://www.luogu.com.cn/problem/P4779
题目描述:给定一个 n 个点,m 条有向边的带非负权图,计算从 s 出发,到每个点的距离。
这道题就是一个单源最短路径的模板,有两种做法:
1.Floyd算法
暴力枚举出所有起点、终点以及中间值,然后算出每两个点间的最小值。
但这个算法时间复杂度较高,是O(n^3),很容易爆掉,在这道题甚至拿不到分。
代码:
- 1 #include<bits/stdc++.h>
- 2 using namespace std;
- 3 int arr[10000][10000];
- 4 int main(){
- 5 int n,m,s,i,j,k,a,b,c;
- 6 cin>>n>>m>>s;
- 7 for(i=1;i<=n;i++){
- 8 for(j=1;j<=n;j++){
- 9 if(i==j){
- 10 arr[i][j]=0;
- 11 }else{
- 12 arr[i][j]=99999999;
- 13 }
- 14 }
- 15 }
- 16 while(m--){
- 17 cin>>a>>b>>c;
- 18 arr[a][b]=min(c,arr[a][b]);
- 19 }
- 20 for(k=1;k<=n;k++){
- 21 for(i=1;i<=n;i++){
- 22 if(i==k||arr[i][k]==99999999){
- 23 continue;
- 24 }
- 25 for(j=1;j<=n;j++){
- 26 arr[i][j]=min(arr[i][j],arr[i][k]+arr[k][j]);
- 27 }
- 28 }
- 29 }
- 30 for(i=1;i<=n;i++){
- 31 cout<<arr[s][i]<<" ";
- 32 }
- 33 }
这道题我们要用一种更高级的算法——
2.dijkstra算法
在无负权边的情况下,时间复杂度为 O(n log n)基本可以顺利通过所有模板题。
先确定初始点到其他所有点的路径(可能为无穷),然后从和该点距离最小点开始遍历,不断更新这些点与初始点的最小距离(学术名叫松弛),最后求出初始点与所有其他点的最短路。
然后要通过此题,还需要前向星存边和优先队列(堆)优化,可能比较难理解,自己画图模拟即可。
上代码(有注释):
- 1 #include<bits/stdc++.h>
- 2 using namespace std;
- 3 long long vis[100001]={0},head[100001],dis[100001],cnt,n,m,s,a,b,c;
- 4 long long INF=2147483647;//2的31次方,可以看做无穷
- 5 struct Q{
- 6 int a,b,c,next;
- 7 };//邻接表,在有向图中存储起点、终点权值,next用来前向星存边
- 8 struct node{//放进优先队列中的结构体
- 9 int w,now;//w为最短路,now为点
- 10 bool operator <(const node &x)const{
- 11 return w>x.w;//权值从大到小排
- 12 }
- 13 };
- 14 priority_queue<node> q;//优先队列
- 15 Q e[500001];
- 16 void add(int a,int b,int c){//前向星存边
- 17 e[cnt++].a=a;
- 18 e[cnt].b=b;
- 19 e[cnt].c=c;
- 20 e[cnt].next=head[a];//next存储上一个cnt值,方便for循环从后往前遍历边
- 21 head[a]=cnt;
- 22 }
- 23 void dijkstra(){
- 24 for(int i=1;i<=n;i++){
- 25 dis[i]=INF;
- 26 }
- 27 dis[s]=0;
- 28 q.push((node){0,s});//将起点压入队列
- 29 while(!q.empty()){//队列非空
- 30 node x=q.top();//弹出堆顶(最小)元素
- 31 q.pop();
- 32 int u=x.now;
- 33 if(vis[u]==1){
- 34 continue;//遍历完无需再遍历
- 35 }
- 36 vis[u]=1;
- 37 for(int i=head[u];i;i=e[i].next){//用前向星遍历
- 38 int v=e[i].b;
- 39 dis[v]=min(dis[v],dis[u]+e[i].c);//松弛操作
- 40 q.push((node){dis[v],v});
- 41 }
- 42 }
- 43 }
- 44 int main(){
- 45 cin>>n>>m>>s;
- 46 for(int i=0;i<m;i++){
- 47 cin>>a>>b>>c;
- 48 add(a,b,c);
- 49 }
- 50 dijkstra();
- 51 for(int i=1;i<=n;i++){
- 52 cout<<dis[i]<<" ";
- 53 }
- 54 }
0016:单源最短路径(dijkstra算法)的更多相关文章
- 单源最短路径Dijkstra算法,多源最短路径Floyd算法
1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...
- 单源最短路径——dijkstra算法
dijkstra算法与prim算法的区别 1.先说说prim算法的思想: 众所周知,prim算法是一个最小生成树算法,它运用的是贪心原理(在这里不再证明),设置两个点集合,一个集合为要求的生成树的 ...
- 单源最短路径 dijkstra算法实现
本文记录一下dijkstra算法的实现,图用邻接矩阵表示,假设图为无向图.而且连通,有向图,不连通图的做法相似. 算法简述: 首先确定"单源"的源.假设是第0个顶点. 维护三个数组 ...
- 单源最短路径——Dijkstra算法学习
每次都以为自己理解了Dijkstra这个算法,但是过没多久又忘记了,这应该是第4.5次重温这个算法了. 这次是看的胡鹏的<地理信息系统>,看完之后突然意识到用数学公式表示算法流程是如此的好 ...
- 单源最短路径-Dijkstra算法
1.算法标签 贪心 2.算法描述 具体的算法描述网上有好多,我觉得莫过于直接wiki,只说明一些我之前比较迷惑的. 对于Dijkstra算法,最重要的是维护以下几个数据结构: 顶点集合S : 表示已经 ...
- [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)
单源最短路径 问题描述 分别求出从起点到其他所有点的最短路径,这次主要介绍两种算法,Dijkstra和SPFA.若无负权优先Dijkstra算法,存在负权选择SPFA算法. Dijkstra算法 非负 ...
- matlab练习程序(单源最短路径Dijkstra)
图的相关算法也算是自己的一个软肋了,当年没选修图论也是一大遗憾. 图像处理中,也有使用图论算法作为基础的相关算法,比如图割,这个算法就需要求最大流.最小割.所以熟悉一下图论算法对于图像处理还是很有帮助 ...
- 单源最短路径---Bellman-Ford算法
传送门: Dijkstra Bellman-Ford SPFA Floyd 1.Dijkstra算法的局限性 像上图,如果用dijkstra算法的话就会出错,因为如果从1开始,第一步dist[2] = ...
- 洛谷P3371单源最短路径Dijkstra版(链式前向星处理)
首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...
- 单源最短路径Dijkstra和优先级算法
百度百科:迪杰斯特拉算法. 代码实现如下: import java.util.Comparator; import java.util.PriorityQueue; import java.util. ...
随机推荐
- netty系列之:netty中的核心编码器bytes数组
目录 简介 byte是什么 netty中的byte数组的工具类 netty中byte的编码器 总结 简介 我们知道netty中数据传输的核心是ByteBuf,ByteBuf提供了多种数据读写的方法,包 ...
- Visual Studio 修改NuGet 包缓存路径
Visual Studio 下载的NuGet包默认会缓存到 C:\Users{Windows用户名}.nuget\packages 下,时间一长就会导致 C盘空间严重不足. 那么怎样去设置,让包缓存文 ...
- [STL] deque 双端队列
- windows使用命令行终止端口的进程
C:\Users\fxz>netstat -ano | find "8093" TCP 0.0.0.0:8093 0.0.0.0:0 LISTENING 3956 TCP [ ...
- 实体linux服务器-由自动ip改为固定ip后,无法上网问题--配置问题解法
新入公司,研发产业为零,开始搞. linux之前是自动获取ip地址的,网上搜索的帖子,耍流氓的居多,不能上网的原因很多,我这个是配置不对,看是否与你的一样. 1.首先看下当前电脑网卡,根据地址可以判断 ...
- 文件共享总结下篇-NFS学习笔记
一.NFS原理 ## 本次实验以CentOS7.7为例 [root@qll251 ~]# cat /etc/redhat-release CentOS Linux release 7.7.1908 ( ...
- git 本地项目关联新repo
git initgit remote add origin repo-url git pull origin master --allow-unrelated-histories git add . ...
- uni-app 中实现 onLaunch 异步回调后执行 onLoad 最佳实践
前言 好久没写博客了,由于公司业务需要,最近接触uiapp比较多,一直想着输出一些相关的文章.正好最近时间富余,有机会来一波输出了. 问题描述 在使用 uni-app 开发项目时,会遇到需要在 onL ...
- Unity实现”对象池管理器“
前言:警告!这可能是坨屎,空闲时间写成,仅作娱乐 在Unity中生成或销毁一个物体会占用较大的资源,如果是制作FPS射击游戏,子弹生成更是雪上加霜.所以我自己写了一个PoolManager,不能和网上 ...
- kruskar重构树
只略略讲一点基本方式与思想了 构建 并查集,边按从小(大)到大(小)加入,建新点,点权为此边权,该点为两点根的父亲. 性质:(此处为最小生成树重构树) 1.lca(u,v)为u到v路径上的最大边权 2 ...