这个算法不能处理负边情况,有负边,请转到Floyd算法或SPFA算法(SPFA不能处理负环,但能判断负环)

SPFA(SLF优化):https://www.cnblogs.com/yifan0305/p/16391419.html

代码很长,耐下心来看完,存储方法为链式前向星存储。

(如果内存放得下的话,建议稠密图用邻接矩阵(或者跑floyd),稀疏图用邻接表,只是建议)

#include<bits/stdc++.h>
using namespace std;
int n,m,cnt;//cnt 计数器 有cnt条边(从1开始存)
struct edge
{
int u,v,w,nxt;
/*u 起点 (不需要的话可以删掉)
v 目标点 w 边权
nxt 指向这条边的上一条边的标号(上一条边是从同一起点发出的边,不要搞混了) */
};
edge e[20020];
int h[2010];//存储第x个点发出的最后一条边的编号
struct nod//存储点
{
int s,w;//s 这个点的标号 w 起点到这个点的最短路径值
};
struct cmp//结构体的比较函数(优先队列要用,看不懂去搜一下,毕竟这里不是它的主场)
{
bool operator()(nod a,nod b)
{
return a.w<b.w;
}
};
nod dis[2010];//存点(毕竟不好处理点的标号和最短路径值相匹配,如果你有更好的方法,忽略这种存法)
bool f[2010];// 标记点是否被染色(看不懂染色的往下看。。。懒得再敲一遍了)
priority_queue<nod,vector<nod>,cmp> q;//定义一个优先队列(存点)
void add(int,int,int);
void dij()//堆优化
{
for(int i=1;i<=n;++i)//初始化
{
dis[i].s=i;//将编号输入
dis[i].w=0x3f3f3f;//将值设为一个很大的值,理由是便于后续使用(废话)
}
dis[1].w=0;//起点到起点的距离是0(该题起点为1,根据题目来)
q.push(dis[1]);//该点入队
while(!q.empty())
{
nod top=q.top();//取出队首元素
int u=top.s,w=top.w;//u 该点的编号 w 起点到点u的最短路径值
f[u]=1;//标记已经被染过色了
//(染色不懂,就理解为这个点已经用过了,标记一下,不能再用了,跟搜索回溯的原理差不多)
q.pop();//出队
for(int i=h[u];i;i=e[i].nxt)//邻接表遍历
{
int v=e[i].v;//v 目标点
if(dis[v].w>w+e[i].w)//松弛操作
{
dis[v].w=w+e[i].w;//更新起点到点v的最短路径值
q.push(dis[v]);//入队
}
if(f[v]) continue;//如果已被染色(看不懂按上面的理解),跳过
//这里松弛和染色不会冲突,松弛操作是更新最优值,染色是为了防止后面扫到该点的非优值(2022.5.15修改)
}
}
}
int main()
{
scanf("%d%d",&n,&m);//输入,根据题目来
for(int a,b,c,i=1;i<=m;++i)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);//加边
add(b,a,c);//加边,如果是有向图,忽略这一步操作
}
dij();//调用函数
if(dis[n].w>=0x3f3f3f-1) printf("-1");
//这里是输出操作,如果起点到点n的值大于0x3f3f3f-1,就说明压根就没更新到,也说明起点和点n不连接
//(题目要求,根据题目来)
else printf("%d",dis[n].w);
return 0;
}
void add(int u,int v,int w)//加边操作
{
e[++cnt].v=v;//记录该条边的目标点
e[cnt].w=w;//记录边权
e[cnt].nxt=h[u];//记录上一条边
h[u]=cnt;//更新从点u发出的最后一条边的边号
}

重载运算符版本

#include<bits/stdc++.h>
using namespace std;
int n,m,cnt,g;//cnt 计数器 有cnt条边(从1开始存)s起点
struct edge
{
int u,v,w,nxt;
/*u 起点 (不需要的话可以删掉)
v 目标点 w 边权
nxt 指向这条边的上一条边的标号(上一条边是从同一起点发出的边,不要搞混了) */
};
edge e[20020];
int h[2010];//存储第x个点发出的最后一条边的编号
struct nod//存储点
{
int s,w;//s 这个点的标号 w 起点到这个点的最短路径值
bool operator < (const nod &a) const
{
return w>a.w;
}//运算符重载
};
nod dis[2010];//存点(毕竟不好处理点的标号和最短路径值相匹配,如果你有更好的方法,忽略这种存法)
bool f[2010];// 标记点是否被染色
priority_queue<nod> q;//定义一个优先队列(存点)
void add(int,int,int);
void dij()//堆优化
{
memset(f,0,sizeof f);//初始化数组
for(int i=1;i<=n;++i)//初始化
{
dis[i].s=i;//将编号输入
dis[i].w=0x3f3f3f;//将值设为一个很大的值
}
dis[g].w=0;//起点到起点的距离是0
q.push(dis[g]);//该点入队
while(!q.empty())
{
nod top=q.top();//取出队首元素
int u=top.s,w=top.w;//u 该点的编号 w 起点到点u的最短路径值
q.pop();//出队
if(f[u]) continue;//如果该点已经染过色了,跳过
f[u]=1;//染色
for(int i=h[u];i;i=e[i].nxt)//邻接表遍历
{
int v=e[i].v;//v 目标点
if(!f[v]&&dis[v].w>w+e[i].w)//松弛操作
{
dis[v].w=w+e[i].w;//更新起点到点v的最短路径值
q.push(dis[v]);//入队
}
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&g);//输入,根据题目来
for(int a,b,c,i=1;i<=m;++i)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);//加边
add(b,a,c);//加边,如果是有向图,忽略这一步操作
}
dij();//调用函数
if(dis[n].w>=0x3f3f3f-1) printf("-1");
//这里是输出操作,如果起点到点n的值大于0x3f3f3f-1,就说明压根就没更新到,也说明起点和点n不连接
else printf("%d",dis[n].w);
return 0;
}
void add(int u,int v,int w)//加边操作
{
e[++cnt].v=v;//记录该条边的目标点
e[cnt].w=w;//记录边权
e[cnt].nxt=h[u];//记录上一条边
h[u]=cnt;//更新从点u发出的最后一条边的边号
}

dijkstra最短路算法(堆优化)的更多相关文章

  1. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  2. Dijkstra最短路算法

    Dijkstra最短路算法 --转自啊哈磊[坐在马桶上看算法]算法7:Dijkstra最短路算法 上节我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最 ...

  3. 【坐在马桶上看算法】算法7:Dijkstra最短路算法

           上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径 ...

  4. 最短路-朴素版Dijkstra算法&堆优化版的Dijkstra

    朴素版Dijkstra 目标 找到从一个点到其他点的最短距离 思路 ①初始化距离dist数组,将起点dist距离设为0,其他点的距离设为无穷(就是很大的值) ②for循环遍历n次,每层循环里找出不在S ...

  5. 最短路模板|堆优化Dijkstra,SPFA,floyd

    Ⅰ:Dijkstra单源点最短路 1.1Dijkstra const int MAX_N = 10000; const int MAX_M = 100000; const int inf = 0x3f ...

  6. Dijkstra算法堆优化详解

    DIJ算法的堆优化 DIJ算法的时间复杂度是\(O(n^2)\)的,在一些题目中,这个复杂度显然不满足要求.所以我们需要继续探讨DIJ算法的优化方式. 堆优化的原理 堆优化,顾名思义,就是用堆进行优化 ...

  7. BZOJ 3040 最短路 (堆优化dijkstra)

    这题不是裸的最短路么?但是一看数据范围就傻了.点数10^6,边数10^7.这个spfa就别想了(本来spfa就是相当不靠谱的玩意),看来是要用堆优化dijkstra了.但是,平时写dijkstra时为 ...

  8. NEU 1664 传送(最短路基础 堆优化Dijkstra)

    题目描述 小A最近喜欢上一款游戏:游戏把地图分了一些区域,这些区域可能会重叠,也可能不会. 游戏中有一项传送技能,改传送技能只能将在同一区域的两个地方使用.小A可以利用区域中重叠部分来实现从某一区域到 ...

  9. Dijkstra算法堆优化

    转自 https://blog.csdn.net/qq_41754350/article/details/83210517 再求单源最短路径时,算法有优劣之分,个人认为在时间方面 朴素dijkstra ...

随机推荐

  1. 《Mybatis 手撸专栏》第7章:SQL执行器的定义和实现

    作者:小傅哥 博客:https://bugstack.cn - <手写Mybatis系列> 一.前言 为什么,要读框架源码? 因为手里的业务工程代码太拉胯了!通常作为业务研发,所开发出来的 ...

  2. JUC的数据库连接池小练习

    JUC练习数据库连接池实现 通过一个连接数组来充当连接池 一个原子的标记数组 通过cas来保持多线程下的安全,用synchronized来进行暂停和唤醒 @Slf4j public class MyC ...

  3. 5┃音视频直播系统之 WebRTC 中的协议UDP、TCP、RTP、RTCP详解

    一.UDP/TCP 如果让你自己开发一套实时互动直播系统,在选择网络传输协议时,你会选择使用UDP协议还是TCP协议 假如使用 TCP 会怎样呢?在极端网络情况下,TCP 为了传输的可靠性,将会进行反 ...

  4. SQL查询与SQL优化[姊妹篇.第四弹]

    在上一篇文章中,我们一起了解了关系模型与关系运算相关的知识,接下来我们一起谈谈,面对复杂的关系数据,我们如何来优化,SQL如何玩转更优呢? 在上一篇中抛出了4个关于优化方面的问题: 1.返回表中0.0 ...

  5. K8S 使用Kubeadm搭建高可用Kubernetes(K8S)集群 - 证书有效期100年

    1.概述 Kubenetes集群的控制平面节点(即Master节点)由数据库服务(Etcd)+其他组件服务(Apiserver.Controller-manager.Scheduler...)组成. ...

  6. Beyond Compare文件对比神器,快来给文件找茬!

    在工作中很多场景下都需要比对两个文件之间的差异,你是否还傻傻的同时打开两个文件,用眼睛一行一行的核对? 赶紧来试试这个神器Beyond Compare!!它可以快速的帮你找出两个文件的差异,而且还有其 ...

  7. 清明欢乐赛(USACO选题)

    总传送门 T1. [USACO19JAN] Redistricting P luogu P5202 思路: 这种每次选出段长有个上限\(k\)的常常是和单调队列有关. 这里是单调队列优化dp 不过一开 ...

  8. 从数字化概念到落地,都说是一道坎,JNPF能为企业带来什么呢?​

    数字经济席卷全球推动产业转型是必然趋势,人类社会正在数字化大潮中发生深刻变革,数字化越来越成为推动经济社会发展的核心驱动力.企业正处于数字经济大潮的风口浪尖,故企业经验决策者应深刻认识数字化转型对于企 ...

  9. Spring-Cloud-Alibaba系列教程(一)Nacos初识

    前言 在2020年即将开启SpringCloudAlibaba的专题,希望2020年共同学习进步. 学习资料 文档 Naco文档 程序猿DD Spring Cloud Aliabab专题 专题博客 视 ...

  10. FTPClient处理中文乱码问题,实测通过了

    使用FTPClient 操作FTP时,遇到路径或文件名中文乱码问题:   其中的一种处理方式:   在new FTPClient()后,可以设置编码, ftpClient=new FTPClient( ...