`
pleasetojava
  • 浏览: 730324 次
  • 性别: Icon_minigender_2
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

每对顶点间的最短距离 稀疏有向图Johnson算法 采用邻接表C++实现

 
阅读更多

每对顶点间的最短距离 稀疏有向图Johnson算法 C++实现

// 稀疏有向图Johnson算法.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<iostream>
#define Infinity 65535
#define MAX 100
using namespace std;

//边尾节点结构体
struct edgeNode
{
int no;//节点序号
int weight; //此边权值
edgeNode *next; //下一条邻接边
};

//节点信息
struct vexNode
{
char info; //节点序号
edgeNode *link; //与此节点为首节点的边的尾节点链表
};

//优先队列元素结构体
struct PriQue
{
int no; //节点元素序号
int weight; //源点到此节点的权值
};

//节点数组
vexNode adjlist[MAX];

//添加一个序号为0节点到其他各节点的最小权值
int d[MAX];
//源点到各节点的最小权值
int lowcost[MAX];
//各节点对间的最小权值
int mincost[MAX][MAX];
//优先队列
PriQue queue[2*MAX];

//建立图的邻接表
void createGraph(vexNode *adjlist,int n,int e)
{
int i;
cout<<"请输入这些节点的信息:"<<endl;
for(i=1;i<=n;i++)
{
cout<<"节点"<<i<<"的名称:";
cin>>adjlist[i].info;
adjlist[i].link = NULL;
}
cout<<"请输入这些边的信息:"<<endl;
int v1,v2;
edgeNode *p1;
int weight1;
for(i=1;i<=e;i++)
{
cout<<"边"<<i<<"的首尾节点:";
cin>>v1>>v2;
cout<<"请输入此边的权值:";
cin>>weight1;
p1 = (edgeNode*)malloc(sizeof(edgeNode));
p1->no = v2;
p1->weight = weight1;
p1->next = adjlist[v1].link;
adjlist[v1].link = p1;
}
//添加节点0,到每一个节点的距离都是0
adjlist[0].info ='0';
adjlist[0].link = NULL;
for(i=n;i>=1;i--)
{
d[i] = 0;
p1 = (edgeNode*)malloc(sizeof(edgeNode));
p1->no = i;
p1->weight = 0;
p1->next = adjlist[0].link;
adjlist[0].link = p1;
}
}

//bellman_ford算法求节点0到其他各节点的最短距离
bool bellman_ford(vexNode *adjlist,int *d,int n)
{
int i,j;
d[0] = 0;
edgeNode *p1;
for(j=1;j<=n;j++)
{
for(i=0;i<=n;i++)
{
p1= adjlist[i].link;
while(p1 != NULL)
{
if(d[p1->no]>d[i]+p1->weight)
d[p1->no] = d[i] + p1->weight;
p1 = p1->next;
}
}
}
for(i=0;i<=n;i++)
{
p1= adjlist[i].link;
while(p1 != NULL)
{
if(d[p1->no]>d[i]+p1->weight)
return false;
p1 = p1->next;
}
}
return true;
}

//johnson算法中,需要对每一条边重新赋权值产生非负的权
void G_w_to_G1_w1(int *d,const int n)
{
int i;
edgeNode *p1;
for(i=0;i<=n;i++)
{
p1= adjlist[i].link;
while(p1 != NULL)
{
p1->weight = p1->weight + d[i] - d[p1->no];
p1 = p1->next;
}
}
}

//保持优先队列的优先性,以指定源点到每一点的最少距离为关键字
void keep_heap(PriQue *queue,int &num,int i)
{
int smallest = i;
int left = 2*i,right = 2*i+1;
if(left<=num&&queue[left].weight<queue[i].weight)
smallest = left;
if(right<=num&&queue[right].weight<queue[smallest].weight)
smallest = right;
if(smallest != i)
{
PriQue q = queue[smallest];
queue[smallest] = queue[i];
queue[i] = q;
keep_heap(queue,num,smallest);
}
}

//插入一个元素到优先队列中,并保持队列优先性
void insert_heap(PriQue *queue,int &num,int no,int wei)
{
num += 1;
queue[num].no = no;
queue[num].weight = wei;
int i = num;
while(i>1&&queue[i].weight<queue[i/2].weight)
{
PriQue q1;
q1 = queue[i/2];
queue[i/2] = queue[i];
queue[i] = q1;
i = i/2;
}
}

//取出队列首元素
PriQue heap_extract_min(PriQue *queue,int &num)
{
if(num<1)
return queue[0];
PriQue que = queue[1];
queue[1] = queue[num];
num = num -1;
keep_heap(queue,num,1);
return que;
}

//dijkstra算法求节点i到其他每一个节点的最短距离
void dijkstra(vexNode *adjlist,PriQue * queue,int i,const int n,int &num)
{
int v = i;
//lowcost[v] = 0;
int j;
for(j=1;j<n;j++)
{
edgeNode *p1 = adjlist[v].link;
while(p1 != NULL)
{
if(lowcost[p1->no] > lowcost[v] + p1->weight)
{
lowcost[p1->no] = lowcost[v] + p1->weight;
insert_heap(queue,num,p1->no,lowcost[p1->no]);
}
p1 = p1->next;
}
v = heap_extract_min(queue,num).no;
if(v==0)
{
cout<<"队列中没有节点!"<<endl;
return;
}
}
}


int _tmain(int argc, _TCHAR* argv[])
{
int cases;
cout<<"请输入案例的个数:";
cin>>cases;
//用队列0元素作为哨兵,如果队列中没有元素,则返回队列0元素
queue[0].no = 0;
queue[0].weight = 0;
while(cases--)
{
int n,e;
cout<<"请输入节点数:";
cin>>n;
cout<<"请输入边数:";
cin>>e;
//队列中的元素,初始为0
int num = 0;
int i,j;
//创建邻接表
createGraph(adjlist,n,e);
cout<<endl;
memset(d,Infinity,sizeof(d));
//bellman_ford算法求节点0到其他各节点的最短距离
bool flag = bellman_ford(adjlist,d,n);
if(!flag)
{
cout<<"此图存在负回路,不正确!"<<endl;
continue;
}
//johnson算法中,需要对每一条边重新赋权值产生非负的权
G_w_to_G1_w1(d,n);
//运用dijkstra算法求得每一对节点间的最短距离
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
lowcost[j] = Infinity;
lowcost[i] =0;
dijkstra(adjlist,queue,i,n,num);
//重新把原值赋值回来,因为在函数G_w_to_G1_w1()中改变过
for(j=1;j<=n;j++)
mincost[i][j] = lowcost[j] + d[j] - d[i];
}
cout<<"下面输出每一对顶点之间的最短距离:"<<endl;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cout<<"顶点("<<i<<":"<<adjlist[i].info<<")到顶点("<<j<<":"<<adjlist[j].info<<")的最短距离为:"<<mincost[i][j]<<endl;
}
}
system("pause");
return 0;
}

-------------------------------------------程序测试----------------------------------------------------------

请输入案例的个数:1
请输入节点数:5
请输入边数:9
请输入这些节点的信息:
节点1的名称:a
节点2的名称:b
节点3的名称:c
节点4的名称:d
节点5的名称:e
请输入这些边的信息:
边1的首尾节点:1 2
请输入此边的权值:3
边2的首尾节点:1 3
请输入此边的权值:8
边3的首尾节点:1 5
请输入此边的权值:-4
边4的首尾节点:2 4
请输入此边的权值:1
边5的首尾节点:2 5
请输入此边的权值:7
边6的首尾节点:3 2
请输入此边的权值:4
边7的首尾节点:4 1
请输入此边的权值:2
边8的首尾节点:4 3
请输入此边的权值:-5
边9的首尾节点:5 4
请输入此边的权值:6

下面输出每一对顶点之间的最短距离:
顶点(1:a)到顶点(1:a)的最短距离为:0
顶点(1:a)到顶点(2:b)的最短距离为:1
顶点(1:a)到顶点(3:c)的最短距离为:-3
顶点(1:a)到顶点(4:d)的最短距离为:2
顶点(1:a)到顶点(5:e)的最短距离为:-4
顶点(2:b)到顶点(1:a)的最短距离为:3
顶点(2:b)到顶点(2:b)的最短距离为:0
顶点(2:b)到顶点(3:c)的最短距离为:-4
顶点(2:b)到顶点(4:d)的最短距离为:1
顶点(2:b)到顶点(5:e)的最短距离为:-1
顶点(3:c)到顶点(1:a)的最短距离为:7
顶点(3:c)到顶点(2:b)的最短距离为:4
顶点(3:c)到顶点(3:c)的最短距离为:0
顶点(3:c)到顶点(4:d)的最短距离为:5
顶点(3:c)到顶点(5:e)的最短距离为:3
顶点(4:d)到顶点(1:a)的最短距离为:2
顶点(4:d)到顶点(2:b)的最短距离为:-1
顶点(4:d)到顶点(3:c)的最短距离为:-5
顶点(4:d)到顶点(4:d)的最短距离为:0
顶点(4:d)到顶点(5:e)的最短距离为:-2
顶点(5:e)到顶点(1:a)的最短距离为:8
顶点(5:e)到顶点(2:b)的最短距离为:5
顶点(5:e)到顶点(3:c)的最短距离为:1
顶点(5:e)到顶点(4:d)的最短距离为:6
顶点(5:e)到顶点(5:e)的最短距离为:0
请按任意键继续. . .

分享到:
评论

相关推荐

    单项海洋环境影响评价等级表.docx

    单项海洋环境影响评价等级表.docx

    基于AT89C51 单片机为核心器件,程序设计采用C 语言,Keil 软件编译程序,配以相关外围接口电路,实现了方波、锯齿波、正弦波、三角波、梯形波五种特定波形的产生【论文+源码】

    【作品名称】:基于AT89C51 单片机为核心器件,程序设计采用C 语言,Keil 软件编译程序,配以相关外围接口电路,实现了方波、锯齿波、正弦波、三角波、梯形波五种特定波形的产生【论文+源码】 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】:本设计中的波形发生器系统要求基于51单片机,因此选用以AT89C51单片机作为整个系统的控制核心,应用其强大的接口功能,构成整个波形发生器的硬件系统。使用C 语言对单片机编程可产生相应的正弦波,方波,三角波,锯齿波梯形波波形信号。在程序运行时,当接收到按键信息后,需要输出某种波形时,调用相应的中断服务子程序和波形发生程序,经电路的数/模转换器和运算放大器处理后,从信号发生器的输出端口输出即可得到要求的波形。 当需要改变频率时只需要改变单片机的波形发生程序中的递增或者递减变量即可。 【资源声明】:本资源作为“参考资料”而不是“定制需求”,代码只能作为参考,不能完全复制照搬。需要有一定的基础看懂代码,自行调试代码并解决报错,能自行添加功能修改代码。

    数学建模培训资料 数学建模实战题目真题答案解析解题过程&论文报告 完全多元图的最大匹配问题研究 共9页.pdf

    数学建模培训资料 数学建模实战题目真题答案解析解题过程&论文报告 完全多元图的最大匹配问题研究 共9页.pdf

    毕设源码-基于Python Web的社区爱心养老管理系统设计与实现_hvhwz--论文-期末大作业+说明文档.rar

    本项目是基于Python Web的社区爱心养老管理系统,旨在为社区养老提供一个全面、高效的管理平台。系统集成了用户管理、老人信息管理、健康管理、活动管理、服务管理等多项功能,通过简洁明了的界面,让管理人员能够轻松地进行各项操作,从而更好地服务于社区老人。 在架构上,系统采用B/S模式,前端使用HTML、CSS、JavaScript等技术,搭配Vue.js框架,实现了用户友好的交互界面;后端则基于Python的Django框架,提供了稳定且高效的服务端逻辑处理能力。数据库选用MySQL,确保了数据的存储安全和高效访问。 开发此项目的目的,不仅是为了满足计算机相关专业学生的毕设需求,提供一个实战练习的平台,更是希望通过实际项目的开发,培养学生的专业技能和实践能力,同时,也希望能为社区养老服务贡献一份力量,通过科技手段,让老年人的生活更加美好、便捷。

    教学版单体spring-petlinic,课程《Kubernetes微服务实践》.zip

    教学版单体spring-petlinic,课程《Kubernetes微服务实践》

    密码学领域的Vigenère多表密码算法解析与实现

    内容概要:本文介绍了16世纪法国外交家Blaise de Vigenère提出的一种多表密码算法,详细解释了Vigenère密码的加密解密机制及其历史应用背景。特别提到了当明文M的长度超过密钥K的情况下,密钥会被重复使用的技巧。 适合人群:对古典密码学感兴趣的初学者,以及希望深入理解密码编码基本原理的学习者。 使用场景及目标:了解Vigenère密码的工作原理,掌握简单的加解密技术,增强信息安全意识。能够自行实施加解密操作,理解经典密码学的基本概念和技术。 其他说明:本文不仅提供了理论讲解,还给出了具体的例子帮助理解和实操练习。

    STM32-EMBPI.PDF

    STM32-EMBPI : Embedded Pi, triple-play platform for STM32, Raspberry Pi and Arduino

    电子电气架构-汽车网络管理策略分析(整车至单件层面)

    内容概要:本文主要探讨了电子电气架构中的网络管理策略,尤其是针对汽车中多个ECU(Electronic Control Unit)的协同管理和低功耗设计。通过引入网络管理状态机的概念,详细介绍了各状态(如常规运行状态、重复报文状态、准备睡眠模式、预睡眠模式、深度睡眠模式等)的具体运作机制及其在汽车电子系统中的重要性。文中还讨论了网络管理报文的设计与传输规则,特别是控制位向量CBV的定义,强调了网络管理在节能降耗方面的关键作用。 适用人群:具备一定汽车电子工程背景的专业人士或研究者,尤其对网络管理及低功耗设计感兴趣的工程师。 使用场景及目标:适用于汽车设计与制造企业的研发部门,帮助其优化电子控制系统,提升产品能效比,降低维护成本,提高用户体验。通过对网络管理策略的理解与应用,达到降低车载电子系统功耗的目的,进而延长电动车的续航能力和降低传统燃油车的油耗。 其他说明:文章不仅提供了理论上的阐述,还包括了具体的操作指南和技术细节,有助于从业者深入理解和实施网络管理方案。同时提醒在现代信息化社会中保持屏蔽力的重要性,鼓励读者专注于自己的发展目标,避免无效的精力分散。

    英飞凌TC3XX-MCAL培训PPT

    英飞凌TC3XX_MCAL培训PPT

    缴费综合服务系-JAVA-基于springBoot高校网上缴费综合服务系统设计与实现

    缴费综合服务系-JAVA-基于springBoot高校网上缴费综合服务系统设计与实现

    Python与机器学习方向,《TensorFlow基础教程》课程仓库.zip

    Python与机器学习方向,《TensorFlow基础教程》课程仓库

    本科毕业设计 基于Python+Django教学资源管理系统网站详细文档+全部资料.zip

    【资源说明】 本科毕业设计 基于Python+Django教学资源管理系统网站详细文档+全部资料.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    电动汽车与软件定义汽车(SDV)时代的汽车行业数字化转型

    内容概要:文章详细讨论了汽车行业正经历的重大变革,尤其是电动汽车(EV)和软件定义汽车(SDV)对行业的深远影响。随着技术的进步,汽车的差异化优势不再仅限于机械硬件,而是越来越多地取决于软件和服务。这一转型要求汽车制造商重新评估现有的解决方案堆栈,加大在电气化和连接性等领域的投资,以实现车型的电气化并支持可扩展性和全生命周期更新。同时,汽车的开发重点已经从机电领域转向了芯片和软件领域,强调基于云计算的协作开发方法。 适合人群:汽车行业专业人士、汽车电子工程师、技术研发人员及政策制定者。 使用场景及目标:帮助读者理解和把握汽车行业数字化转型的趋势,指导他们在电动汽车和软件定义汽车领域做出正确的技术投资和战略调整。 其他说明:本文不仅讨论了技术变革,还深入剖析了由此带来的商业和运营模式的变化,为汽车行业的未来发展方向提供了洞见。

    微信课堂助手 微信小程序+PHP毕业设计 源码+数据库+论文+启动教程.zip

    微信课堂助手 微信小程序+PHP毕业设计 源码+数据库+论文+启动教程

    新设博士后科研工作站备案申请表.xlsx

    新设博士后科研工作站备案申请表.xlsx

    的玩具 Python 实现.zip

    的玩具 Python 实现手套蟒蛇GloVe的玩具 Python 实现。Glove 产生单词的密集向量嵌入,其中一起出现的单词在生成的向量空间中靠得很近。虽然这会产生与word2vec (在gensim中有一个很棒的 python 实现)类似的嵌入,但方法不同GloVe 通过对语料库词共现矩阵的对数进行分解来产生嵌入。代码采用异步随机梯度下降,用Cython实现,很可能存在大量bug。安装使用 pip 从 pypi 安装pip install glove_python。OSX 用户请注意由于使用 OpenMP,glove-python 无法在 Clang 下编译。要安装它,您需要一个较新的版本gcc(例如来自 Homebrew)。应该由 接收setup.py如果没有,请打开一个问题。使用 OSX 中包含的默认 Python 发行版进行构建也不受支持请尝试 Homebrew 或 Anaconda 中的版本。用法生成嵌入分为两个步骤从语料库中创建共现矩阵,然后使用它生成嵌入。该类Corpus有助于从可交互的标记构建语料库该类Glove训练嵌入(使

    消息中间件rabbitmq学习的一些代码、笔记.zip

    消息中间件rabbitmq学习的一些代码、笔记

    java毕设项目之基于javaweb宿舍管理系统(源码+说明文档+mysql).zip

    环境说明:开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat 开发软件:eclipse/myeclipse/idea Maven包:Maven 浏览器:谷歌浏览器。 项目均可完美运行

    空气质量现状评价表.docx

    空气质量现状评价表.docx

    建设工程施工现场消防安全检查表.docx

    建设工程施工现场消防安全检查表.docx

Global site tag (gtag.js) - Google Analytics