【C/C++】Dijkstra算法的简洁实现
Dijkstra的实现有很多种,下面给出一种较为简洁和高效的实现,可以作为模板快速使用。
1. 使用邻接表存储图;
2. 使用标准STL的vector存储每个点的所有邻接边;
3. 使用pair记录当前搜索的点,pair<int,int>对:
first记录最小距离,用以在优先队列中实现类似'最小堆优化';
second记录该最小距离对应的点;
4. 使用priority_queue实现优化;(附使用方法)
5. 一个细节:这是盲目检索,中途若D[i] < p.first,说明队列里的该点已经到达了,这个pair已经无效,直接continue;
实现:
#include<bits/stdc++.h>
#define INF 100000005
#define MAX 100006
using namespace std; typedef pair<int,int> P; struct edge{
int to;
int cost;
edge(int t,int c):to(t),cost(c){
}
}; const int N = ;
vector<edge> g[N];
int D[N]; //距离
int n,m; //n个点 m条边 void Dijkstra(int s){
priority_queue<P,vector<P>,greater<P> > que; //小端优先队列
fill(D,D+MAX,INF);//注意必须初始化为最大
D[s] = ;
que.push(P(,s));
while(!que.empty()){
P p = que.top();
que.pop();
int v = p.second;
if(D[v] < p.first) continue; //说明该点无需重复
for(int i = ;i<g[v].size();i++) {
//遍历所有后续边
edge e = g[v][i];
int to = e.to;
int cost = e.cost;
if(D[to] > D[v] + cost){
D[to] = D[v] + cost;
que.push(P(D[to],to));
}
}
}
} int main(){
cin>>n>>m;
int a,b,d;
//Vector<edge> g[MAX]的初始化
for(int i = ;i<MAX;i++) {
g[i].clear();
}
//距离D的初始化
//fill(D,D+MAX,INF) ;//等Dijkstra时再初始化也行
for(int i = ;i<m;i++){
cin>>a>>b>>d;
g[a].push_back(edge(b,d));
g[b].push_back(edge(a,d));
}
int s,t;//起点 终点
s = ;
t = n;
Dijkstra(s);
cout<<D[n]<<endl;
return ;
}
【Appendix】
priority_queue的使用方法:
- 对于基本数据:
- priority_queue<int> q;
- priority_queue<int,vector<int>,less<int> > q; //默认,less可以省
- 这创建的是‘大 ’优先队列,大的在top
- 取:q.top();
- 出:q.pop();
- 放:q.push(int);
- 创建‘小 ’优先队列:
- priority_queue<int,vector<int>,greater<int> > q;
- 对于结构体数据:
- 1. 结构体运算符重载
bool operator < (const struct1,const struct1) const{
return ?;
}
- 2. 定义cmp函数,做参数传入,更加灵活
bool cmp(struct1,struct2){
return ?;
}
priority_queue<struct1,vector<struct2>,cmp> q;
【C/C++】Dijkstra算法的简洁实现的更多相关文章
- Dijkstra算法求解最短路径分析
最短路径是图论算法中的经典问题.图分为有向图.无向图,路径权值有正值.负值,针对不同的情况需要分别选用不同的算法.在维基上面给出了各种不同的场景应用不同的算法的基本原则:最短路问题. 针对无向图,正权 ...
- Dijkstra算法and Floyd算法 HDU 1874 畅通工程续
Dijkstra算法描述起来比较容易:它是求单源最短路径的,也就是求某一个点到其他各个点的最短路径,大体思想和prim算法差不多,有个数组dis,用来保存源点到其它各个点的距离,刚开始很好办,只需要把 ...
- 图论之最短路径(1)——Floyd Warshall & Dijkstra算法
开始图论学习的第二部分:最短路径. 由于知识储备还不充足,暂时不使用邻接表的方法来计算. 最短路径主要分为两部分:多源最短路径和单源最短路径问题 多源最短路径: 介绍最简单的Floyd Warshal ...
- 基于STL优先队列和邻接表的dijkstra算法
首先说下STL优先队列的局限性,那就是只提供入队.出队.取得队首元素的值的功能,而dijkstra算法的堆优化需要能够随机访问队列中某个节点(来更新源点节点的最短距离). 看似可以用vector配合m ...
- Dijkstra算法的另一种证明
按:今天看Tanenbaum的计算机网络时讲到了Dijkstra算法.关于算法的正确性,<算法导论>给出了严格的证明.CLRS的证明基于一个通用的框架,非常清晰.今天只是随意想想是否有其他 ...
- 图论算法(四)Dijkstra算法
最短路算法(三)Dijkstra算法 PS:因为这两天忙着写GTMD segment_tree,所以博客可能是seg+图论混搭着来,另外segment_tree的基本知识就懒得整理了-- Part 1 ...
- 求两点之间最短路径-Dijkstra算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.D ...
- Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解
/* Dijkstra算法用优先队列来实现,实现了每一条边最多遍历一次. 要知道,我们从队列头部找到的都是到 已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其 ...
- 关于dijkstra算法的一点理解
最近在准备ccf,各种补算法,图的算法基本差不多看了一遍.今天看的是Dijkstra算法,这个算法有点难理解,如果不深入想的话想要搞明白还是不容易的.弄了一个晚自习,先看书大致明白了原理,就根据书上的 ...
随机推荐
- 安装屏保软件(Linux终端演示 “黑客帝国” 字母雨界面)和Linux修改管理员密码
1.Linux修改管理员密码:打开终端:1. 重启 reboot 2.进入内核登陆系统点击e3.进入系统救援界面,定位Linux16所在行,找到ro 后删除,在此位置添加一条命令: rw init= ...
- 网络最大流算法—最高标号预流推进HLPP
吐槽 这个算法.. 怎么说........ 学来也就是装装13吧.... 长得比EK丑 跑的比EK慢 写着比EK难 思想 大家先来猜一下这个算法的思想吧:joy: 看看人家的名字——最高标号预留推进 ...
- iOS----------YYModel
weaterInfoModel *weather = [weaterInfoModel yy_modelWithDictionary:returnData[@"weatherinfo&quo ...
- 想要在launcher中模拟按home键。
Intent mHomeIntent = new Intent(Intent.ACTION_MAIN); mHomeIntent.addCategory(Intent.CATEGORY_HOME); ...
- 如何开启红米手机4X的ROOT超级权限
红米手机4X通过什么方法拥有了root权限?大家都清楚,Android机器有root权限,如果手机拥有了root相关权限,可以实现更强的功能,举个栗子大家公司的营销部门同事,使用大多数营销软件都需要在 ...
- dede后台删除文章后台还有分页显示解决方法
打开dede目录中content_list.php 大概在100行左右 $sql = "SELECT COUNT(*) AS dd FROM `#@__arctiny` $tinyQuery ...
- 关于Python, ftplib模块中的cwd()进入含中文目录失败的问题
使用Python的ftplib模块连接ftp服务器时, 使用cwd()连接含中文的目录, 报错 : UnicodeEncodeError: 'latin-1' codec can't encode c ...
- Windows系统XAMPP安装Moodle教程
一.安装工具下载: 系统环境: Operating System: Windows 10 Enterprise 64-bit (10.0, Build 17134) 集成软件: XAMPP Versi ...
- MySQL游标循环取出空值的BUG
早上同事要我写个MySQL去除重复数据的SQL,想起来上次写过一篇MySQL去除重复数据的博客,使用导入导出加唯一索引实现的,但是那种方式对业务影响较大,所以重新写一个存储过程来删重复数据,这一写就写 ...
- linux内核调试技巧之一 dump_stack【转】
在内核中代码调用过程难以跟踪,上下文关系复杂,确实让人头痛 调用dump_stack()就会打印当前cpu的堆栈的调用函数了. 如此,一目了然的就能看到当前上下文环境,调用关系了 假设: 遇到uvc_ ...