/*
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队列实现的理解的更多相关文章

  1. dijkstra算法优先队列

    d[i] 是起点到 I 节点的最短距离 void Dijkstra(int s) { priority_queue<P, vector<P>, greater<P> &g ...

  2. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  3. 基于STL优先队列和邻接表的dijkstra算法

    首先说下STL优先队列的局限性,那就是只提供入队.出队.取得队首元素的值的功能,而dijkstra算法的堆优化需要能够随机访问队列中某个节点(来更新源点节点的最短距离). 看似可以用vector配合m ...

  4. HDU 1535 Invitation Cards(逆向思维+邻接表+优先队列的Dijkstra算法)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1535 Problem Description In the age of television, n ...

  5. dijkstra算法与优先队列

    这是鄙人的第一篇技术博客,作为算法小菜鸟外加轻度写作障碍者,写技术博客也算是对自己的一种挑战和鞭策吧~ 言归正传,什么是dijkstra算法呢? -dijkstra算法是一种解决最短路径问题的简单有效 ...

  6. Dijkstra算法(朴素实现、优先队列优化)

    Dijkstra算法只能求取边的权重为非负的图的最短路径,而Bellman-Ford算法可以求取边的权重为负的图的最短路径(但Bellman-Ford算法在图中存在负环的情况下,最短路径是不存在的(负 ...

  7. dijkstra算法之优先队列优化

    github地址:https://github.com/muzhailong/dijkstra-PriorityQueue 1.题目 分析与解题思路 dijkstra算法是典型的用来解决单源最短路径的 ...

  8. 单源最短路径算法——Bellman-ford算法和Dijkstra算法

     BellMan-ford算法描述 1.初始化:将除源点外的所有顶点的最短距离估计值 dist[v] ← +∞, dist[s] ←0; 2.迭代求解:反复对边集E中的每条边进行松弛操作,使得顶点集V ...

  9. ACM: HDU 1874 畅通工程续-Dijkstra算法

    HDU 1874 畅通工程续 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Desc ...

随机推荐

  1. javascript 全局对象--w3school

    JavaScript全局对象 1.  decodeURI()解析某个编码的URI. 2.decodeURInComponent()解析一个编码的URI组件. 3.encodeURI()把字符串编码为U ...

  2. goEasy消息推送,pushlet 向特写用户实时推送

    goEasy 1先去goEasy官网注册goeasy.io,并创建application,得到superKey 2引入js <script type="text/javascript& ...

  3. gulp使用配置

    gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学习起来很容易,而且gulpjs使用的是nodejs中stream来读取和操作数据,其速 ...

  4. C++构造函数/析构函数 设置成private的原因

    C++构造函数/析构函数 设置成private的原因 标签(空格分隔): c/c++ 将构造函数,析构函数声明为私有和保护的,那么对象如何创建? 已经不能从外部调用构造函数了,但是对象必须被构造,应该 ...

  5. Linux入门之路

    一.linux简介 Linux前身:Minix,由Andrew S. Tanenbaum教授参考Unix编写 Linux创始人:Linus Torvalds Linux内核版(只有内核)和发行版(在内 ...

  6. photoshop

    photoshop裁剪 photoshop裁剪快捷键是C键: 使用photoshop裁剪工具裁切出图片的方法: 选择好所需要的图片,右键保存到本地计算机' 在photoshop中打开这张图片(文件/打 ...

  7. Ajax的二次封装

    function handleAjax(url,_data,method) { return ajax(url,_data,method).then(function (res) { if(res){ ...

  8. ex2-注释和井号

    代码: print("I could have code like this.") # and the commnt after is ignored.# You can also ...

  9. DBImport v3.5 中文版发布:数据库定时同步及文档生成工具(IT人员必备)

    前言: 趁着最近的休息时间,只能多勤快些:多写代码,多更新文章. 因为一旦投入新的工作,估计博客又会恢复到一年才产几篇的状态. 对于DBImport,因为用户的意见,增加了一个亮点功能,让软件B格升为 ...

  10. CYQ.Data V5 MDataTable 专属篇介绍

    前言 以前一两个月才出一篇,这三天有点变态地连续1天1篇(其实都是上周末两天写好的存货). 短期应该没有新的和此框架相关的文章要写了,这应该是最后一篇,大伙且看且珍惜. 前两篇讲数据库读写分离和分布式 ...