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+ 链式前向星+ 堆优化(优先队列)的更多相关文章

  1. 模板 Dijkstra+链式前向星+堆优化(非原创)

    我们首先来看一下什么是前向星.   前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序, 并记录下以某个点为起点的所有边在数组中的起始位置和 ...

  2. HDU 2544最短路 【dijkstra 链式前向星+优先队列优化】

    最开始学最短路的时候只会用map二维数组存图,那个时候还不知道这就是矩阵存图,也不懂得效率怎么样 经过几个月的历练再回头看最短路的题, 发现图可以用链式前向星来存, 链式前向星的效率是比较高的.对于查 ...

  3. 单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板

    一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的 ...

  4. Floyd && Dijkstra +邻接表 +链式前向星(真题讲解来源:城市路)

    1381:城市路(Dijkstra) 时间限制: 1000 ms         内存限制: 65536 KB提交数: 4066     通过数: 1163 [题目描述] 罗老师被邀请参加一个舞会,是 ...

  5. UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

    最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同 ...

  6. 最短路 spfa 算法 && 链式前向星存图

    推荐博客  https://i.cnblogs.com/EditPosts.aspx?opt=1 http://blog.csdn.net/mcdonnell_douglas/article/deta ...

  7. SPFA_queue_链式前向星最短路 & HDU2433

    题目大意:看完之后,觉得不肯能让我暴力,比较好想的就是初始化——每个点都求个最短路spfa,sum数组记录每个点到各个点的最短路之和,ans作为总和,之后一一删除边u-v,求关于u的最短路,如果dis ...

  8. UESTC 30.最短路-最短路(Floyd or Spfa(链式前向星存图))

    最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同 ...

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

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

随机推荐

  1. python any and all function

    1 any 如果iterable object至少有一个元素是true的时候,返回为true.空的iterable object返回为false. 2 all 如果iterable object中的每 ...

  2. Use of implicitly declared global variable

    https://stackoverflow.com/questions/7604419/resharper-javascript-use-of-implicitly-declared-global-v ...

  3. Swift-AES之加密解密

    什么是AES 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代 ...

  4. 在java中除去字符串(String)中的换行字符(\r \n \t)

    我们先来看几个例子: 例1: public class Test { public static void main(String[] args) { String s = "'sds gd ...

  5. 频繁项集------->产生强关联规则的过程

    频繁项集------->产生强关联规则的过程 1.由Apriori算法(当然别的也可以)产生频繁项集 2.根据选定的频繁项集,找到它所有的非空子集 3.强关联规则需要满足最小支持度和最小置性度  ...

  6. Android 在eclipse中没有出现AVD的解决方法(转载)

    转自:http://frabbit2013.blog.51cto.com/1067958/1243549 本文主要介绍在系统中成功配置好Android开发环境(即SDK is ok and ADT o ...

  7. 疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)

    P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...

  8. set && muliset

    #include <set> #include <iostream> #include <cstdio> #include <cctype> using ...

  9. HDU 4691 后缀数组+RMQ

    思路: 求一发后缀数组,求个LCP 就好了 注意数字有可能不只一位 (样例2) //By SiriusRen #include <bits/stdc++.h> using namespac ...

  10. Win7上安装Oracle数据库

    由于ORACLE并没有FOR WIN7的版本,必须下载for vista_w2k8这个版本,将oralce 10G的安装镜像解压到硬盘,然后修改安装目录下的rehost.xml和oraparam.in ...