【最短路】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版(链式前向星处理)
首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...
随机推荐
- JavaScript基础 -- BOM
JavaScript三大核心: 1)核心(ECMAScript):描述了JS的语法和基本对象 2)文档对象模型(DOM):处理网页内容的方法和接口 3)浏览器对象模型(BOM):与浏览器交互的方法和接 ...
- JavaScript实现页面重载 - 535种方式
location = location ... and a 534 other ways to reload the page with JavaScript location = location ...
- Called attach on a child which is not detached
问题:Called attach on a child which is not detached: ViewHolder#出现问题的原因 经过google后发现,出现该问题的原因是由于recycle ...
- SPOOL 命令使用实例【oracle导出纯文本格式文件】
SPOOL 命令使用实例[oracle导出纯文本格式文件] SET echo off --在用start命令执行一个sql脚本时,是否显示脚本中正在执行的SQL语句: SET ...
- android.content.ReceiverCallNotAllowedException: 解决方法
一. android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to reg ...
- hdu 5782(kmp+hash)
Cycle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- Maven 项目管理 —— 安装与配置
Maven 是一种全新的项目构建方式,基于项目对象模型(POM,Project Object Model)的思想,Maven 可以管理项目的整个生命周期,包括编译.构建(build).测试.发布以及报 ...
- Linux 下安装配置 JDK7(转载)
转自:http://dawndiy.com/archives/155/ 自从从Oracle收购Sun近三年来,已经有很多变化.早在8月,甲骨文将“Operating System Distributo ...
- Linux文件详解
一.Linux文件类型分:普通文件.目录文件.链接文件.设备文件.管道文件. 1.普通文件:由ls -al显示属性时,第一个属性为 [-],例如 [-rwxrwxrwx].包括: 纯文本文件(ASCI ...
- [Usaco2018 Open]Disruption
Description Farmer John自豪于他所经营的交通发达的的农场.这个农场是由N块牧场(2≤N≤50,000)组成的,N-1条双向道路将它们连接起来,每一条道路的都为一单位长度.Farm ...