【最短路】Dijkstra+ 链式前向星+ 堆优化(优先队列)
Dijkstra+ 链式前向星+ 优先队列
Dijkstra算法
Dijkstra最短路算法,个人理解其本质就是一种广度优先搜索。先将所有点的最短距离Dis[ ]都刷新成∞(涂成黑色),然后从起点x (Dis[x]= 0, Dis[]值最小 )开始查询;先将x 加入(涂成灰色),对x 的所有边进行遍历,对所有搜索到的点x+ 1 进行松弛(刷新),若经过x 点的松弛,得到的距离小于原来的值:Dis[x]+ dis(x, x+ 1) < Dis[x+ 1], 则用新值刷新,把x+ 1加入(涂成灰色);当x 的所有边都完毕,邻接的点都松弛完毕后,把x 退出(涂成白色),继续从下一个Dis[ ]最小的点开始;重复上述步骤,直到所有的点都涂成白色,退出。
链式前向星
这个不说了,之前的帖子里说过,拉到最下面就是。
堆优化
利用优先队列,对数据结构感兴趣的可以去看一下堆,这里就不说了,会用优先队列就行。
最短路计算:Dijkstra+ 链式前向星+ 优先队列
下面进入正题。
还是拆分代码和用例题来解释。
①链式前向星建图
using namespace std;
const int MAX_E= ;
const int MAX_V= ;
const int inf= 0x3f3f3f3f; struct ENode
{
int to; //终点;
int w; //权;
int type; //路的类型;
int next; //下一条路的地址;
};
ENode Edegs[MAX_E];
int Head[MAX_V]; //点Vi的第一条边的地址;
int Dis[MAX_V]; //点Vi到起点的最短距离;
int main()
{
int n, m, s;
cin >> n >> m >> s;
int t, a, b, w;
memset(Head, -, sizeof(Head));
for (int i= ; i< m; i ++)
{
cin >>a >>b >>w;
Edegs[i].to= b;
Edegs[i].w= w;
Edegs[i].next= Head[a];
Head[a]= i;
//// 有向图建图多加一次边,m 变成m* 2;
// ++ i;
// Edegs[i].to= a;
// Edegs[i].w= w;
// Edegs[i].next= Head[b];
// Head[b]= i;
}
return ;
}
②Dijkstra+ 优先队列
int Head[MAX_V]; //点Vi的第一条边的地址;
int Dis[MAX_V]; //点Vi到起点的最短距离;
struct cmpx
{
//优先队列的排序函数;
bool operator()(int &a,int &b)const
{
return Dis[a]> Dis[b];
}
};
void Dijkstra(int x)
{
//用优先队列寻找Dis[]最小点;
//代替遍历搜索,节约时间;
priority_queue<int,vector<int>,cmpx > q;
memset(Dis, inf, sizeof(Dis)); //染成黑色;
Dis[x]= ;
q.push(x); //将x 加入队列,涂成灰色; while (! q.empty())
{
int u= q.top();
q.pop(); //将x 出队列,涂成白色;
for (int k= Head[u]; k!= -; k= Edegs[k].next )
{
int v= Edegs[k].to;
if (Dis[v]> Dis[u]+ Edegs[k].w )
{
Dis[v]= Dis[u]+ Edegs[k].w;
q.push(v); //将x+ 1加入队列,涂成灰色;
}
}
}
}
下面是洛谷上一道最短路入门题,验证一下正确性:P3371 【模板】单源最短路径(弱化版)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
const int MAX_E= ;
const int MAX_V= ;
const int inf= 0x3f3f3f3f; struct ENode
{
int to; //终点;
int w; //权;
int type; //路的类型;
int next; //下一条路的地址;
};
ENode Edegs[MAX_E];
int Head[MAX_V]; //点Vi的第一条边的地址;
int Dis[MAX_V]; //点Vi到起点的最短距离;
struct cmpx
{
//优先队列的排序函数;
bool operator()(int &a,int &b)const
{
return Dis[a]> Dis[b];
}
};
inline int read()
{
//快速读入;
int X= ,w= ;
char ch= ;
while(ch<'' || ch>'')
{
if(ch=='-') w= -;
ch= getchar();
}
while(ch>= '' && ch<= '') X= (X<< )+(X<< )+(ch-''),ch=getchar();
return X* w;
}
void Dijkstra(int x)
{
//用优先队列寻找Dis[]最小点;
//代替遍历搜索,节约时间;
priority_queue<int,vector<int>,cmpx > q;
memset(Dis, inf, sizeof(Dis)); //染成黑色;
Dis[x]= ;
q.push(x); //将x 加入队列,涂成灰色; while (! q.empty())
{
int u= q.top();
q.pop(); //将x 出队列,涂成白色;
for (int k= Head[u]; k!= -; k= Edegs[k].next )
{
int v= Edegs[k].to;
if (Dis[v]> Dis[u]+ Edegs[k].w )
{
Dis[v]= Dis[u]+ Edegs[k].w;
q.push(v); //将x+ 1加入队列,涂成灰色;
}
}
}
} int main()
{
int n, m, s;
cin >> n >> m >> s;
int t, a, b, w;
memset(Head, -, sizeof(Head));
for (int i= ; i< m; i ++)
{
cin >>a >>b >>w;
Edegs[i].to= b;
Edegs[i].w= w;
Edegs[i].next= Head[a];
Head[a]= i;
//// 有向图建图多加一次边,m 变成m* 2;
// ++ i;
// Edegs[i].to= a;
// Edegs[i].w= w;
// Edegs[i].next= Head[b];
// Head[b]= i;
}
Dijkstra(s);
for (int i = ; i <= n; i ++)
{
if (i!= ) printf(" ");
if (Dis[i]== inf)
{
printf("");
}
else
{
printf("%d", Dis[i]);
}
}
printf("\n");
return ;
}
完整程序
谢谢观看这篇随笔!
【最短路】Dijkstra+ 链式前向星+ 堆优化(优先队列)的更多相关文章
- 模板 Dijkstra+链式前向星+堆优化(非原创)
我们首先来看一下什么是前向星. 前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序, 并记录下以某个点为起点的所有边在数组中的起始位置和 ...
- HDU 2544最短路 【dijkstra 链式前向星+优先队列优化】
最开始学最短路的时候只会用map二维数组存图,那个时候还不知道这就是矩阵存图,也不懂得效率怎么样 经过几个月的历练再回头看最短路的题, 发现图可以用链式前向星来存, 链式前向星的效率是比较高的.对于查 ...
- 单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板
一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的 ...
- Floyd && Dijkstra +邻接表 +链式前向星(真题讲解来源:城市路)
1381:城市路(Dijkstra) 时间限制: 1000 ms 内存限制: 65536 KB提交数: 4066 通过数: 1163 [题目描述] 罗老师被邀请参加一个舞会,是 ...
- UESTC30-最短路-Floyd最短路、spfa+链式前向星建图
最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同 ...
- 最短路 spfa 算法 && 链式前向星存图
推荐博客 https://i.cnblogs.com/EditPosts.aspx?opt=1 http://blog.csdn.net/mcdonnell_douglas/article/deta ...
- SPFA_queue_链式前向星最短路 & HDU2433
题目大意:看完之后,觉得不肯能让我暴力,比较好想的就是初始化——每个点都求个最短路spfa,sum数组记录每个点到各个点的最短路之和,ans作为总和,之后一一删除边u-v,求关于u的最短路,如果dis ...
- UESTC 30.最短路-最短路(Floyd or Spfa(链式前向星存图))
最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同 ...
- 洛谷P3371单源最短路径Dijkstra版(链式前向星处理)
首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...
随机推荐
- socketserver模块三次登陆验证,身份验证
帅爆太阳的男人 1,socketserver是解决TCP服务器和多个客户端进行通信 服务器: import socketserver class MySocket(socketserver,BaseR ...
- ZOJ 3872 计算对答案的贡献
D - Beauty of Array Description Edward has an array A ...
- 第二次PHP面试题
昨天下午翘班去参加了人生中第二次PHP面试.是一家相对第一家更加专业的互联网公司.效果不如第一家理想,笔试题有点难,而且偏高理论,面试时面试官也还不错,一起探讨,可是他的问题我还是很多都不知道,果然是 ...
- 蓝桥 PREV-30 历届试题 波动数列 【动态规划】
历届试题 波动数列 时间限制:1.0s 内存限制:256.0MB 问题描述 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个数列中后一项总是比前一项增加2或者减少3. ...
- HIbernate- SQLQuery 简易
package cn.demo; import java.util.Arrays; import java.util.List; import org.hibernate.SQLQuery; impo ...
- Eclipse 工程配置与目录结构及各种文件夹(常用插件)
.classpath..project 是 Eclipse 工程所必须的文件. OpenExplorer: 该 jar 包的下载地址:samsonw/OpenExplorer 安装配置方法:eclip ...
- Window 无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll。尝试重新安装该程序以解决此问题。
现象: 解决办法: 方法一:缺什么补什么 http://www.greenxf.com/soft/125654.html 把api-ms-win-crt-runtime-l1-1-0.dll下载到电脑 ...
- ubuntu16.04 查看CPU是几核
ubuntu 16.04下查看机器是cpu是几核的 几个cpu more /proc/cpuinfo |grep "physical id"|uniq|wc -l 每个cpu是几核 ...
- 百度上传组件 WebUploader
WebUploader http://fex.baidu.com/webuploader/doc/index.html WebUploader API 文档详细解读 源码以及示例:https://gi ...
- 【WIP_S2】递归
创建: 2018/01/14 递归 定义 自己召唤自己 通用形式 if (基本情况A的处理) { ... return 值A } else if (基本情况B的处理) ...