Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解

 1 /*
 2 Dijkstra算法用优先队列来实现,实现了每一条边最多遍历一次。 要知道,我们从队列头部找到的都是到
 3 已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其他点(被更新的节点可以在队列中
 4 ,也可以是非队列中的节点)的距离 。
 5 
 6 如果v节点的到更新,则直接放入队列中(pair<d[v], v>)不会重复放入到队列中
 7 
 8 如果某个节点从队列中出来的时候,如果cur.first != dist[cur.second] 就是 cur.second这个节点一开始
 9 被更新的最短距离值 和 现在得到的最短距离的值dist[cur.second] 不想等,说明该节点已经被之前队列中
10 具有更短距离的节点更新过了, 那么新的节点pair(dist[cur.second], cur.second)再次放入优先队列中,用来跟新其他节点的最短距离。 如果想等,则dist[cur.second]就是cur.second最终的最短距离!
11 */
12 #include<iostream> 
13 #include<queue>
14 #include<cstring> 
15 #define N 1000
16 using namespace std;
17 
18 class EDGE
19 {
20   public:
21     int u, v, w;
22     int next;//和节点 u 相连的下一条边的编号 
23 };
24 
25 EDGE edge[2*N];
26 
27 typedef pair<int, int>pii;//pair<距离,节点号>
28 
29 int first[N];//最多有N个节点 ,建立每个节点和其相连的边的关系 
30 int dist[N];//源点到各个点的最短距离 
31 
32 int n, m;//节点数,边数 
33 
34 bool operator >(pii a, pii b)
35 {
36    if(a.first==b.first)
37      return a.second > b.second;
38    return a.first > b.first;//按照最短的距离值在队列的前段
39 }
40 
41 priority_queue<pii, vector<pii>, greater<pii> >q; 
42 
43 void Dijkstra()
44 {
45    pii cur;
46    memset(dist, 0x3f, sizeof(dist));
47    dist[1]=0;//另节点 1 为源点
48    q.push(make_pair(0, 1));
49    while(!q.empty()) 
50    {
51       cur=q.top();
52       q.pop();
53       if(cur.first != dist[cur.second])  continue;// 不等于的话说明该节点的值已经经过其他节点松弛为更短的距离值了 
54       for(int e=first[cur.second]; e!=-1; e=edge[e].next)
55         if(dist[edge[e].v]>dist[edge[e].u]+edge[e].w)
56         {
57                dist[edge[e].v]=dist[edge[e].u]+edge[e].w;
58                q.push(make_pair(dist[edge[e].v], edge[e].v));//将更新之后的节点的放入队列之中 
59         }
60    }
61 }
62 
63 int main()
64 {
65    int i;
66    cin>>n>>m;
67    for(i=1; i<=n; ++i)
68      first[i]=-1; 
69    for(i=0; i<m; ++i)
70    {
71        cin>>edge[i].u>>edge[i].v>>edge[i].w;
72        edge[edge[i].u].next=first[edge[i].u];
73        first[edge[i].u]=i;
74    } 
75    Dijkstra();
76    for(i=2; i<=n; ++i)
77      cout<<"1->"<<i<<":"<<dist[i]<<endl; 
78    return 0;
79 } 
 1 /*
 2 Bellman_Ford算法用队列实现和 Dijkstra算法用优先队列来实现相同的地方是,都是 层次 更新到节点的最短距离,
3 都是将具有最短距离的节点(如果不在队列中)放入队列中 4 Bellman_Ford算法中实现的是带有负权图的最短距离,因为负权的关系,这样可能使得某个 5 节点的最短路径的值一直被更新(比如存在负权回路的时候),所以被更新的节点(如果不在队列中)一直会进入队列中 6 */ 7 #include<iostream> 8 #include<queue> 9 #include<cstring> 10 #define N 1000 11 using namespace std; 12 13 class EDGE 14 { 15 public: 16 int u, v, w; 17 int next;//和节点 u 相连的下一条边的编号 18 }; 19 20 EDGE edge[2*N]; 21 22 int first[N];//最多有N个节点 ,建立每个节点和其相连的边的关系 23 int dist[N];//源点到各个点的最短距离 24 int cnt[N];//记录每个节点在队列中出现的次数 25 int vis[N];//记录当前的节点是否已经在队列中 26 27 int n, m;//节点数,边数 28 29 30 queue<int>q; 31 32 int Bellman_Ford() 33 { 34 int cur; 35 memset(dist, 0x3f, sizeof(dist)); 36 dist[1]=0;//另节点 1 为源点 37 q.push(1); 38 while(!q.empty()) 39 { 40 cur=q.front(); 41 q.pop(); 42 vis[cur]=0;//出队列 43 ++cnt[cur]; 44 if(cnt[cur]>n-1)//如果不存在负权回路,那么某个节点的最多被更新的次数为 n-1 次 45 return 0; 46 for(int e=first[cur]; e!=-1; e=edge[e].next) 47 if(dist[edge[e].v]>dist[edge[e].u]+edge[e].w) 48 { 49 dist[edge[e].v]=dist[edge[e].u]+edge[e].w; 50 if(!vis[edge[e].v])//本跟新的节点没有在队列中 51 { 52 q.push(edge[e].v);//将更新之后的节点的放入队列之中 53 vis[edge[e].v]=1;//放入队列 54 } 55 } 56 } 57 return 1; 58 } 59 60 int main() 61 { 62 int i; 63 cin>>n>>m; 64 for(i=1; i<=n; ++i) 65 first[i]=-1; 66 for(i=0; i<m; ++i) 67 { 68 cin>>edge[i].u>>edge[i].v>>edge[i].w; 69 edge[edge[i].u].next=first[edge[i].u]; 70 first[edge[i].u]=i; 71 } 72 if(!Bellman_Ford())//表示存在负权回路 73 cout<<"不存在最短路径"<<endl; 74 else 75 { 76 for(i=2; i<=n; ++i) 77 cout<<"1->"<<i<<":"<<dist[i]<<endl; 78 } 79 return 0; 80 }

 

 

转载于:https://www.cnblogs.com/hujunzheng/p/3781817.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/532000.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php times33,PHP Hash算法:Times33算法代码实例

最近看书&#xff0c;里面提到了一些Hash算法。比较有印象的是Times33&#xff0c;当时理解不是很透测&#xff0c;今天写了段程序来验证了一下。先上代码&#xff1a;复制代码 代码如下:/*** CRC32 Hash function* param $str* return int*/function hash32($str){return crc3…

捡到vivo手机怎么清除账号_为什么现在买手机,很少会去考虑OPPO和vivo呢?看一下老板怎么说...

不知道大家是否注意到&#xff0c;近年来OPPO和vivo的报道越来越少&#xff0c;而华为、荣耀和小米出现的频率越来越高。此外&#xff0c;网络上还有另外一个声音&#xff0c;一个专业的机友朋友说&#xff0c;宁可选择小米、OPPO和vivo&#xff0c;为什么熟悉自己手机的人不考…

php分析图片中水印的位置,关于ThinkPHP打水印及设置水印位置的分析

这篇文章主要介绍了ThinkPHP打水印及设置水印位置的方法,结合实例形式分析了thinkPHP打印与设置水印的相关操作步骤与具体实现技巧,需要的朋友可以参考下本文实例讲述了ThinkPHP打水印及设置水印位置的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;最近在用Thin…

华为交换机命令_华为交换机常用命令

华为交换机常用命令&#xff1a;1、display current-configuration 显示当前配置2、display interface GigabitEthernet 1/1/4 显示接口信息3、display packet-filter interface GigabitEthernet 1/1/4 显示接口acl应用信息4、display acl all 显示所有acl设置 3900系列交换机5…

java中两种添加监听器的策略

/*第一种&#xff1a;将事件的处理委托给其他对象&#xff0c;下面的例子是委托给了MyListener&#xff08;implements ActionListener&#xff09;*/ 1 import java.applet.Applet;2 import java.awt.event.*;3 import java.awt.*;4 public class ChangeColor extends Applet{…

php dos命令用不了,windows下如何使用DOS命令强制复制文件

有的时候&#xff0c;我们可能需要替换某些目录下的一些文件&#xff0c;手动去一个个目录找的话&#xff0c;就会比较麻烦&#xff0c;这时候&#xff0c;就是我们程序员上场的时候了&#xff0c;程序虽然好写&#xff0c;但是dos命令并不是每个人都玩的转的&#xff0c;而且最…

java的栈图形演示

1 import java.awt.*;2 import javax.swing.*;3 import java.awt.event.*;4 /*5 指示发生了组件定义的动作的语义事件。当特定于组件的动作&#xff08;比如被按下&#xff09;发生时&#xff0c;由组件&#xff08;比如 Button&#xff09;生成此高级别事件。6 事件被传递给每…

python播放本地视频_python opencv 读取本地视频文件 修改ffmpeg的方法

Python opencv 读取视频的三种情况&#xff1a;情况一&#xff1a;通过摄像头采集视频情况二&#xff1a;通过本地视频文件获取视频情况三&#xff1a;通过摄像头录制视频&#xff0c;再读取录制的视频摄像头采集、本地视频文件的读取、写视频文件&#xff0c;网上都有代码。我…

kali里PHP文件502错误,解决Linux Kali iptables开放22端口失败等一系列问题

这篇文章是针对2020年下载安装的kali系统碰到的关于 iptables开放22端口失败等一系列问题的解决办法&#xff0c;如果是其它系统&#xff0c;可以借鉴一下思路。各种报错&#xff1a;# sudo systemctl start iptablesFailed to start iptables.service: Unit iptables.service …

中缀试转后缀试及前缀试并计算其结果

1 /*2 参考大神nb的代码&#xff0c;感觉思路不错&#xff01;终于搞明白了&#xff01;一开始不明白在计算表达式的时候&#xff0c;利用栈到底做了什么&#xff01;现在感觉我们利用栈就是模拟我们书面上计算表达式&#xff0c;3 将优先级高的运算先计算出来&…

ros如何编译python文件_Python为ROS编写一个简单的发布者和订阅者

Python为ROS编写一个简单的发布者和订阅者1.创建工作空间1.1建立文件夹hello_rospy,再在该目录下建立子目录src,并创建工作空间mkdir -p ~/hello_rospy/srccd ~/hello_rospy/srccatkin_init_workspace1.2 编译cd ~/hello_rospy/catkin_make1.3设置运行环境echo "source ~/…

php整站防注入程序,php通用防注入程序 推荐

function jk1986_checksql(){$bad_str "and|select|update|‘|delete|insert|*";$bad_Array explode("|",$bad_str);/** 过滤Get参数 **/foreach ($bad_Array as $bad_a){foreach ($_GET as $g){if (substr_count(strtolower($g),$bad_a) > 0){echo &…

表达式建树

//用数组实现树 1 #include<iostream> 2 #include<ctype.h>3 #include<cstring>4 #define N 100005 #define optd 16 #define optr 27 using namespace std;8 int treeL[N], treeR[N];9 class node 10 { 11 public: 12 int flag;//区分当前节点是操作符还…

python label标签的作用_label标签的作用是什么?

label标签的作用是为鼠标用户改进了可用性&#xff0c;当用户点击【】标签中的文本时&#xff0c;浏览器就会自动将焦点转到和该标签相关联的控件上。label标签的作用&#xff1a;一、标签定义及用法在html中&#xff0c;标签通常和标签一起使用&#xff0c;标签为input元素定义…

java异常自定义返回信息,Spring Boot 如何自定义返回错误码错误信息

说明在实际的开发过程中,很多时候要定义符合自己业务的错误码和错误信息&#xff0c;而不是统一的而不是统一的下面这种格式返回到调用端INTERNAL_SERVER_ERROR(500, "Internal Server Error"),下面我们来看看如何将我们自定义的错误码和错误信息返回到调用端。1 自定…

文件管理系统_Python学习第170节--Linux文件管理系统实际操作和具体介绍

【每天几分钟&#xff0c;从零入门python编程的世界&#xff01;】上节我们简单了解了Linux文件管理系统&#xff0c;现在我们学习它的实际操作。首先我们解释下~和/的区别。~之前我们介绍过&#xff0c;我们说~是Linux系统的根目录&#xff0c;其实这个说法是不准确的&#xf…

redis 计数器 java_Redis 的 8 大应用场景!

之前讲过Redis的介绍&#xff0c;及使用Redis带来的优势&#xff0c;这章整理了一下Redis的应用场景&#xff0c;也是非常重要的&#xff0c;学不学得好&#xff0c;能正常落地是关键。下面一一来分析下Redis的应用场景都有哪些。1、缓存缓存现在几乎是所有中大型网站都在用的必…

sql中in与php数组,格式化SQL“IN”子句的PHP数组

我正在尝试在数据库中查询“product_id”包含在产品ID数组中的记录.该数组是多选输入(< select>)的结果,如下所示&#xff1a;$clients Array ([0] > 80000016-1302638679[1] > 8000003B-1329924004)我想将该数组传递给sql语句的“IN”子句,例如&#xff1a;$sql …

汇编汉诺塔

1 .3862 .model flat3 .stack 40964 include io.h5 ExitProcess proto near32 stdcall, ExitCode:dword6 cr equ 0dh7 lf equ 0ah8 .data9 string1 byte "请输入汉诺塔数&#xff1a;", cr, lf 10 strNum byte 10 dup(?) 11 result byte 10 dup( ) 12 byte c…

oracle精度说明符1~38_Oracle 错误代码总结及解决方案

ORA-00001&#xff1a;违反唯一约束条件(主键错误)ORA-00028&#xff1a;无法连接数据库进程ORA-00900&#xff1a;无效sql语句ORA-00904&#xff1a;字段名写错或是建表时最后一个字段有逗号ORA-00907&#xff1a;缺少右括号ORA-00911&#xff1a;无效字符ORA-00917&#xff1…