【最短路】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版(链式前向星处理)
首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...
随机推荐
- VMware14秘钥
VMware虚拟机已升级至14版本,之前的12版本的秘钥已经无法使用,在此分享一下VMware Workstation 14永久激活密钥: CG54H-D8D0H-H8DHY-C6X7X-N2KG6 ...
- go10---struct
package main import ( "fmt" ) type test struct{} //空的结构体 type person struct { name string ...
- vim升级到8.0
1.卸载 sudo apt-get remove --purge vim 2.添加8.0的vim源并安装 sudo add-apt-repository ppa:jonathonf/vim sudo ...
- 8-2 canvas专题-线条样式
8-2 canvas专题-线条样式 学习要点 对第五章知识进行简单的回顾和总结 进一步讲解canvas绘图相关的知识点 第八章内容介绍 在第八章中我们将对以前的知识进行简单的回顾,着重对canvas绘 ...
- Java 过滤器、监听器、拦截器的区别
原文:http://www.360doc.com/content/10/0601/09/495229_30616324.shtml 1.过滤器 Servlet中的过滤器Filter是实现了ja ...
- Keepalived+lvs 搭建高可用负载均衡
本站点停止更新,请访问:blog.coocap.com 不了解负载均衡高可用的童鞋,强烈建议先看keepalived+nginx高可用负载均衡: 传送门(求粉):http://www.cnblogs. ...
- HDU2138 素数判定
HDU2138 给定N个32位大于等于2的正整数 输出其中素数的个数 用Miller Rabin 素数判定法 效率很高 数学证明比较复杂,略过, 会使用这个接口即可. #include<iost ...
- java用户角色权限设计
实现业务系统中的用户权限管理 B/S系统中的权限比C/S中的更显的重要,C/S系统因为具有特殊的客户端,所以访问用户的权限检测可以通过客户端实现或通过客户端+服务器检测实现,而B/S中,浏览器是每一台 ...
- Linux 上安装 Node.js
Linux 上安装 Node.js 直接使用已编译好的包(在个人阿里云服务器47.100.6.106上安装) Node 官网已经把 linux 下载版本更改为已编译好的版本了,我们可以直接下载解压后使 ...
- oracle给用户授权
1.在PLSQL里,用sys(oracle系统用户)登陆,登陆的时候一定要选择SYSDBA.普通用户登陆选择normal就可以了 2.创建用户 *也可以给普通用户授权为dba即数据库管理员.在导入导出 ...