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 ...
随机推荐
- linux下的tcp连接超时
最近需要写一个linux下的通信程序, 通信模块用的是Qt的QTcpSocket. 最后程序需要增加一个断网检测, 在windows下调试没问题, 拔网线, 断网口都能马上检测到, 但到了部署到lin ...
- HDU 3584 Cube (三维 树状数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3584 Cube Problem Description Given an N*N*N cube A, ...
- python 安装
http://www.aichengxu.com/view/37456 http://blog.csdn.net/tiantiandjava/article/details/17242345 tar ...
- JMF框架
Java媒体框架(JMF)使你能够编写出功能强大的多媒体程序,却不用关心底层复杂的实现细节.JMF API的使用相对比较简单,但是能够满足几乎所有多媒体编程的需求.在这篇文章中,我将向你介绍如何用很 ...
- MongoDB 由于目标计算机积极拒绝,无法连接 2014-07-25T11:00:48.634+0800 warning: Failed to connect to 127.0.0.1:27017, reason: errno:10061
转载自:http://www.cnblogs.com/xiaoit/p/3867573.html 1:启动MongoDB 2014-07-25T11:00:48.634+0800 warning: F ...
- Python之路【第六篇】python基础 之面向对象进阶
一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 和 issubclass(su ...
- PCA与LDA的区别与联系
由于涉及内容较多,这里转载别人的博客: http://blog.csdn.net/sunmenggmail/article/details/8071502 其实主要在于:PCA与LDA的变换矩阵不同, ...
- RemoteIE 开发者可跨平台使用IE测试网页
RemoteIE,这是一个基于微软Azure的服务,它允许开发者在最新版本的IE(Windows 10技术预览版)中测试他们的网页,而不需要安装或在虚拟机中设置对应的系统.要想使用这项服务,开发者需要 ...
- 阿里聚安全受邀参加SFDC安全大会,分享互联网业务面临问题和安全创新实践
现今,技术引领的商业变革已无缝渗透入我们的日常生活,「技术改变生活」的开发者们被推向了创新浪潮的顶端.国内知名的开发者技术社区 SegmentFault 至今已有四年多了,自技术问答开始,他们已经发展 ...
- (DNS被劫持所导致的)QQ音乐与视频网页打开很慢的解决方法
这周开始发现一个很让人抓狂的现象,QQ音乐网页(http://y.qq.com)与QQ视频(http://v.qq.com/)网页打开超慢,甚至是无法打开,严重影响了业余的音乐视频生活. 以QQ视频为 ...