Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解
/*
Dijkstra算法用优先队列来实现,实现了每一条边最多遍历一次。 要知道,我们从队列头部找到的都是到
已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其他点(被更新的节点可以在队列中
,也可以是非队列中的节点)的距离 。 ////如果v节点的到更新,则直接放入队列中(pair<d[v], v>)不会重复放入到队列中 如果某个节点从队列中出来的时候,如果cur.first != dist[cur.second] 就是 cur.second这个节点一开始
被更新的最短距离值 和 现在得到的最短距离的值dist[cur.second] 不想等,说明该节点已经被之前队列中
具有更短距离的节点更新过了, 那么新的节点pair(dist[cur.second], cur.second)再次放入优先队列中,用来跟新其他节点的最短距离。 如果想等,则dist[cur.second]就是cur.second最终的最短距离!
*/
#include<iostream>
#include<queue>
#include<cstring>
#define N 1000
using namespace std; class EDGE
{
public:
int u, v, w;
int next;//和节点 u 相连的下一条边的编号
}; EDGE edge[*N]; typedef pair<int, int>pii;//pair<距离,节点号> int first[N];//最多有N个节点 ,建立每个节点和其相连的边的关系
int dist[N];//源点到各个点的最短距离 int n, m;//节点数,边数 bool operator >(pii a, pii b)
{
if(a.first==b.first)
return a.second > b.second;
return a.first > b.first;//按照最短的距离值在队列的前段
} priority_queue<pii, vector<pii>, greater<pii> >q; void Dijkstra()
{
pii cur;
memset(dist, 0x3f, sizeof(dist));
dist[]=;//另节点 1 为源点
q.push(make_pair(, ));
while(!q.empty())
{
cur=q.top();
q.pop();
if(cur.first != dist[cur.second]) continue;// 不等于的话说明该节点的值已经经过其他节点松弛为更短的距离值了
for(int e=first[cur.second]; e!=-; e=edge[e].next)
if(dist[edge[e].v]>dist[edge[e].u]+edge[e].w)
{
dist[edge[e].v]=dist[edge[e].u]+edge[e].w;
q.push(make_pair(dist[edge[e].v], edge[e].v));//将更新之后的节点的放入队列之中
}
}
} int main()
{
int i;
cin>>n>>m;
for(i=; i<=n; ++i)
first[i]=-;
for(i=; i<m; ++i)
{
cin>>edge[i].u>>edge[i].v>>edge[i].w;
edge[edge[i].u].next=first[edge[i].u];
first[edge[i].u]=i;
}
Dijkstra();
for(i=; i<=n; ++i)
cout<<"1->"<<i<<":"<<dist[i]<<endl;
return ;
}
/*
Bellman_Ford算法用队列实现和 Dijkstra算法用优先队列来实现相同的地方是,都是 层次 更新到节点的最短距离,
3 都是将具有最短距离的节点(如果不在队列中)放入队列中
Bellman_Ford算法中实现的是带有负权图的最短距离,因为负权的关系,这样可能使得某个
节点的最短路径的值一直被更新(比如存在负权回路的时候),所以被更新的节点(如果不在队列中)一直会进入队列中
*/
#include<iostream>
#include<queue>
#include<cstring>
#define N 1000
using namespace std; class EDGE
{
public:
int u, v, w;
int next;//和节点 u 相连的下一条边的编号
}; EDGE edge[*N]; int first[N];//最多有N个节点 ,建立每个节点和其相连的边的关系
int dist[N];//源点到各个点的最短距离
int cnt[N];//记录每个节点在队列中出现的次数
int vis[N];//记录当前的节点是否已经在队列中 int n, m;//节点数,边数 queue<int>q; int Bellman_Ford()
{
int cur;
memset(dist, 0x3f, sizeof(dist));
dist[]=;//另节点 1 为源点
q.push();
while(!q.empty())
{
cur=q.front();
q.pop();
vis[cur]=;//出队列
++cnt[cur];
if(cnt[cur]>n-)//如果不存在负权回路,那么某个节点的最多被更新的次数为 n-1 次
return ;
for(int e=first[cur]; e!=-; e=edge[e].next)
if(dist[edge[e].v]>dist[edge[e].u]+edge[e].w)
{
dist[edge[e].v]=dist[edge[e].u]+edge[e].w;
if(!vis[edge[e].v])//本跟新的节点没有在队列中
{
q.push(edge[e].v);//将更新之后的节点的放入队列之中
vis[edge[e].v]=;//放入队列
}
}
}
return ;
} int main()
{
int i;
cin>>n>>m;
for(i=; i<=n; ++i)
first[i]=-;
for(i=; i<m; ++i)
{
cin>>edge[i].u>>edge[i].v>>edge[i].w;
edge[edge[i].u].next=first[edge[i].u];
first[edge[i].u]=i;
}
if(!Bellman_Ford())//表示存在负权回路
cout<<"不存在最短路径"<<endl;
else
{
for(i=; i<=n; ++i)
cout<<"1->"<<i<<":"<<dist[i]<<endl;
}
return ;
}
Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解的更多相关文章
- dijkstra算法优先队列
d[i] 是起点到 I 节点的最短距离 void Dijkstra(int s) { priority_queue<P, vector<P>, greater<P> &g ...
- 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)
关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...
- 基于STL优先队列和邻接表的dijkstra算法
首先说下STL优先队列的局限性,那就是只提供入队.出队.取得队首元素的值的功能,而dijkstra算法的堆优化需要能够随机访问队列中某个节点(来更新源点节点的最短距离). 看似可以用vector配合m ...
- HDU 1535 Invitation Cards(逆向思维+邻接表+优先队列的Dijkstra算法)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1535 Problem Description In the age of television, n ...
- dijkstra算法与优先队列
这是鄙人的第一篇技术博客,作为算法小菜鸟外加轻度写作障碍者,写技术博客也算是对自己的一种挑战和鞭策吧~ 言归正传,什么是dijkstra算法呢? -dijkstra算法是一种解决最短路径问题的简单有效 ...
- Dijkstra算法(朴素实现、优先队列优化)
Dijkstra算法只能求取边的权重为非负的图的最短路径,而Bellman-Ford算法可以求取边的权重为负的图的最短路径(但Bellman-Ford算法在图中存在负环的情况下,最短路径是不存在的(负 ...
- dijkstra算法之优先队列优化
github地址:https://github.com/muzhailong/dijkstra-PriorityQueue 1.题目 分析与解题思路 dijkstra算法是典型的用来解决单源最短路径的 ...
- 单源最短路径算法——Bellman-ford算法和Dijkstra算法
BellMan-ford算法描述 1.初始化:将除源点外的所有顶点的最短距离估计值 dist[v] ← +∞, dist[s] ←0; 2.迭代求解:反复对边集E中的每条边进行松弛操作,使得顶点集V ...
- ACM: HDU 1874 畅通工程续-Dijkstra算法
HDU 1874 畅通工程续 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Desc ...
随机推荐
- 文件处理命令:sed
使用:sed [-nefr] actionaction:-i直接修改读取的档案内容,而不是由屏幕输出,-r表示支持延伸型正则表达式的语法.动作说明:[n1[,n2]] function n1,n2表示 ...
- ASCII和16进制对照表
十六进制代码 MCS 字符或缩写 DEC 多国字符名 ASCII 控制字符 1 00 NUL 空字符 01 SOH 标题起始 (Ctrl/A) 02 STX 文本起始 (Ctrl/B) 03 ETX ...
- javaweb学习记录(1)
Java基础学习笔录 1.运行java程序,出现bad version number in.class file 编译器()的版本号高于运行环境(jre)的版本号,可以降低编译器版本号,也可以通过提升 ...
- Spring mvc Security安全配置
Spring Security笔记:自定义Login/Logout Filter.AuthenticationProvider.AuthenticationToken SPRING SECURITY ...
- jquery简单插件写法
(function($){ /** * 遮罩插件 * 使用:$('#id').qloading(options); * 详见:/plugins/_11_qloading/qloading.html * ...
- PHP:( && )逻辑与运算符使用说明
第一次看到以下语句的写法大惑不解 ($mCfg['LockChinaIp']==1 && (int)$_SESSION['AdminUserId']==0 && sub ...
- 抓包工具Wireshark过滤器
抓包工具WireShark分为两种过滤器: 捕捉过滤器(CaptureFilters) 显示过滤器(DisplayFilters) 捕捉过虑器语法: Protocol Direction Host ...
- C及C++中typedef的简单使用指南
又是在学数据结构的时候,发现了之前学习的知识遗忘很多,在发现对C/C++中关键字typedef的理解还是没有到位后,我翻阅了学C++用到的课本,又问了度娘,也看了不少关于typedef用法的博客.于是 ...
- 公司内部培训AlwaysOn PPT分享
公司内部培训AlwaysOn PPT分享 下载地址: http://files.cnblogs.com/files/lyhabc/alwayson.ppt
- SOA相关资料整理分享
昨@幸福框架同学问能否推荐SOA一些资,.想想之前看过不少资料文档,就整理分享下,有需要的可以参考下. 文章链接 理解面向服务的体系结构中企业服务总线场景和解决方案,第 1 部分 SOA 和 web ...