题目链接:https://www.luogu.com.cn/problem/P4779

题目描述:给定一个 n 个点,m 条有向边的带非负权图,计算从 s 出发,到每个点的距离。

这道题就是一个单源最短路径的模板,有两种做法:

1.Floyd算法

暴力枚举出所有起点、终点以及中间值,然后算出每两个点间的最小值。

但这个算法时间复杂度较高,是O(n^3),很容易爆掉,在这道题甚至拿不到分。

代码:

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 int arr[10000][10000];
  4. 4 int main(){
  5. 5 int n,m,s,i,j,k,a,b,c;
  6. 6 cin>>n>>m>>s;
  7. 7 for(i=1;i<=n;i++){
  8. 8 for(j=1;j<=n;j++){
  9. 9 if(i==j){
  10. 10 arr[i][j]=0;
  11. 11 }else{
  12. 12 arr[i][j]=99999999;
  13. 13 }
  14. 14 }
  15. 15 }
  16. 16 while(m--){
  17. 17 cin>>a>>b>>c;
  18. 18 arr[a][b]=min(c,arr[a][b]);
  19. 19 }
  20. 20 for(k=1;k<=n;k++){
  21. 21 for(i=1;i<=n;i++){
  22. 22 if(i==k||arr[i][k]==99999999){
  23. 23 continue;
  24. 24 }
  25. 25 for(j=1;j<=n;j++){
  26. 26 arr[i][j]=min(arr[i][j],arr[i][k]+arr[k][j]);
  27. 27 }
  28. 28 }
  29. 29 }
  30. 30 for(i=1;i<=n;i++){
  31. 31 cout<<arr[s][i]<<" ";
  32. 32 }
  33. 33 }

这道题我们要用一种更高级的算法——

2.dijkstra算法

在无负权边的情况下,时间复杂度为 O(n log n)基本可以顺利通过所有模板题。

先确定初始点到其他所有点的路径(可能为无穷),然后从和该点距离最小点开始遍历,不断更新这些点与初始点的最小距离(学术名叫松弛),最后求出初始点与所有其他点的最短路。

然后要通过此题,还需要前向星存边和优先队列(堆)优化,可能比较难理解,自己画图模拟即可。

上代码(有注释):

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 long long vis[100001]={0},head[100001],dis[100001],cnt,n,m,s,a,b,c;
  4. 4 long long INF=2147483647;//2的31次方,可以看做无穷
  5. 5 struct Q{
  6. 6 int a,b,c,next;
  7. 7 };//邻接表,在有向图中存储起点、终点权值,next用来前向星存边
  8. 8 struct node{//放进优先队列中的结构体
  9. 9 int w,now;//w为最短路,now为点
  10. 10 bool operator <(const node &x)const{
  11. 11 return w>x.w;//权值从大到小排
  12. 12 }
  13. 13 };
  14. 14 priority_queue<node> q;//优先队列
  15. 15 Q e[500001];
  16. 16 void add(int a,int b,int c){//前向星存边
  17. 17 e[cnt++].a=a;
  18. 18 e[cnt].b=b;
  19. 19 e[cnt].c=c;
  20. 20 e[cnt].next=head[a];//next存储上一个cnt值,方便for循环从后往前遍历边
  21. 21 head[a]=cnt;
  22. 22 }
  23. 23 void dijkstra(){
  24. 24 for(int i=1;i<=n;i++){
  25. 25 dis[i]=INF;
  26. 26 }
  27. 27 dis[s]=0;
  28. 28 q.push((node){0,s});//将起点压入队列
  29. 29 while(!q.empty()){//队列非空
  30. 30 node x=q.top();//弹出堆顶(最小)元素
  31. 31 q.pop();
  32. 32 int u=x.now;
  33. 33 if(vis[u]==1){
  34. 34 continue;//遍历完无需再遍历
  35. 35 }
  36. 36 vis[u]=1;
  37. 37 for(int i=head[u];i;i=e[i].next){//用前向星遍历
  38. 38 int v=e[i].b;
  39. 39 dis[v]=min(dis[v],dis[u]+e[i].c);//松弛操作
  40. 40 q.push((node){dis[v],v});
  41. 41 }
  42. 42 }
  43. 43 }
  44. 44 int main(){
  45. 45 cin>>n>>m>>s;
  46. 46 for(int i=0;i<m;i++){
  47. 47 cin>>a>>b>>c;
  48. 48 add(a,b,c);
  49. 49 }
  50. 50 dijkstra();
  51. 51 for(int i=1;i<=n;i++){
  52. 52 cout<<dis[i]<<" ";
  53. 53 }
  54. 54 }

0016:单源最短路径(dijkstra算法)的更多相关文章

  1. 单源最短路径Dijkstra算法,多源最短路径Floyd算法

    1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...

  2. 单源最短路径——dijkstra算法

    dijkstra算法与prim算法的区别   1.先说说prim算法的思想: 众所周知,prim算法是一个最小生成树算法,它运用的是贪心原理(在这里不再证明),设置两个点集合,一个集合为要求的生成树的 ...

  3. 单源最短路径 dijkstra算法实现

    本文记录一下dijkstra算法的实现,图用邻接矩阵表示,假设图为无向图.而且连通,有向图,不连通图的做法相似. 算法简述: 首先确定"单源"的源.假设是第0个顶点. 维护三个数组 ...

  4. 单源最短路径——Dijkstra算法学习

    每次都以为自己理解了Dijkstra这个算法,但是过没多久又忘记了,这应该是第4.5次重温这个算法了. 这次是看的胡鹏的<地理信息系统>,看完之后突然意识到用数学公式表示算法流程是如此的好 ...

  5. 单源最短路径-Dijkstra算法

    1.算法标签 贪心 2.算法描述 具体的算法描述网上有好多,我觉得莫过于直接wiki,只说明一些我之前比较迷惑的. 对于Dijkstra算法,最重要的是维护以下几个数据结构: 顶点集合S : 表示已经 ...

  6. [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)

    单源最短路径 问题描述 分别求出从起点到其他所有点的最短路径,这次主要介绍两种算法,Dijkstra和SPFA.若无负权优先Dijkstra算法,存在负权选择SPFA算法. Dijkstra算法 非负 ...

  7. matlab练习程序(单源最短路径Dijkstra)

    图的相关算法也算是自己的一个软肋了,当年没选修图论也是一大遗憾. 图像处理中,也有使用图论算法作为基础的相关算法,比如图割,这个算法就需要求最大流.最小割.所以熟悉一下图论算法对于图像处理还是很有帮助 ...

  8. 单源最短路径---Bellman-Ford算法

    传送门: Dijkstra Bellman-Ford SPFA Floyd 1.Dijkstra算法的局限性 像上图,如果用dijkstra算法的话就会出错,因为如果从1开始,第一步dist[2] = ...

  9. 洛谷P3371单源最短路径Dijkstra版(链式前向星处理)

    首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...

  10. 单源最短路径Dijkstra和优先级算法

    百度百科:迪杰斯特拉算法. 代码实现如下: import java.util.Comparator; import java.util.PriorityQueue; import java.util. ...

随机推荐

  1. Quantexa CDI(场景决策智能)Syneo平台介绍

    Quantexa 大数据服务提供商, 使用实体解析, 关系分析和人工智能技术帮助客户进行数据处理和预防金融犯罪. 企业概览 2016年成立, 当前规模500人 服务特色是场景决策智能CDI(conte ...

  2. 攻防世界-MISC:give_you_flag

    这是攻防世界新手练习区的第四题,题目如下: 点击附件一下载,打开后发现是一个gif动图 可以看到动图有一瞬间出现了一个二维码,找一个网站给他分离一下 得到一张不完整的二维码(然后就不知道该怎么办了,菜 ...

  3. XCTF练习题---MISC---Ditf

    XCTF练习题---MISC---Ditf flag:flag{Oz_4nd_Hir0_lov3_For3ver} 解题步骤: 1.观察题目,下载附件 2.这道题是安恒办的一场比赛题目,下载附件以后是 ...

  4. 《手把手教你》系列基础篇(九十五)-java+ selenium自动化测试-框架之设计篇-java实现自定义日志输出(详解教程)

    1.简介 前面宏哥一连几篇介绍如何通过开源jar包Log4j.jar.log4j2.jar和logback实现日志文件输出,Log4j和logback确实很强大,能生成三种日志文件,一种是保存到磁盘的 ...

  5. day02 真正的高并发还得看IO多路复用

    教程说明 C++高性能网络服务保姆级教程 首发地址 day02 真正的高并发还得看IO多路复用 本节目的 使用epoll实现一个高并发的服务器 从单进程讲起 上节从一个基础的socket服务说起我们实 ...

  6. stm32F103RCT6使用FFT运算分析波形详解(非常新手)

    最近学校电赛院队招新,出的招新题就是低频示波器的.之前一直没有弄懂FFT,借着这次机会实现了一下. FFT原理详解 FFT,就是快速傅里叶变换,这个操作能够将时域信号转化成频域信号,然后对信号进行分析 ...

  7. git 配置别名简化命令行和删除别名

    废话不多说直接上添加别名语法 加上--global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用. git config --global alias.<自己想要的命令行> & ...

  8. 1.SSH协议学习笔记

    一.SSH介绍 介绍: SSH全称是Secure Shell,安全外壳协议. 端口号:22: 如何查看服务端口号: grep ssh /etc/services netstat -antup | gr ...

  9. 真香!Windows 可直接运行 Linux 了

    点击关注上方"开源Linux", 后台回复"读书",有我为您特别筛选书籍资料~ 之前了解过一些适用于Linux的Windows子系统,最近又听人提起,于是在自己 ...

  10. python爬取豆瓣电影Top250(附完整源代码)

    初学爬虫,学习一下三方库的使用以及简单静态网页的分析.就跟着视频写了一个爬取豆瓣Top250排行榜的爬虫. 网页分析 我个人感觉写爬虫最重要的就是分析网页,找到网页的规律,找到自己需要内容所在的地方, ...