图的最短路径dijkstra算法
想法是这样的:
1. 最开始要建立4个list,分别存储
a. 所有的Vertex: allVertex[]
b. 一个空的Vertex list: emptyVertex[]
c. 一个前缀表 previous list(用来回溯路径用): previous[]
d. 一个表示最短距离的表(就是表示某个点与0点的最短距离):
前两个list是用来辅助操作的,后2个表则是输出,通过后2个表我们能得到想要的一切结果。
因此我们的任务其实就是,最终把c。d两个表填充完毕即可。
2. 我们要做一个循环,循环次数为VertexMax次,因为如果是连通图,每次循环都能处理一个Vertex。
3. 第一次循环前我们把start这个vertex从allVertex表,移动到emptyVertex表。
4. 这样我们就需要遍历,与empty表所有vertex关联的每一条line。找出这些line中最短的一条。
5. 找到最短的这条line之后,更新一下previous表,previous[line->end] = start; 然后更新一下distances表, (distances[line->end]) 同 (distances[start] + line->weight)取最小值
6. 然后,line->end作为新的start,重新进入循环。。重复3-5步即可。
#include <iostream>
using namespace std;const int MAX_VERTEX = 5;//图的顶点数
const int MAX_INT = 0x7fffffff;//4字节的整数
const int MIN_INT = 0xffffffff;//4字节的整数
enum Kind{NG, DG};//无向图,有向图
Kind k = NG;//图的种类
int graph[MAX_VERTEX][MAX_VERTEX];//图
int emptyVertex[MAX_VERTEX];//空的Vertex集合
int allVertex[MAX_VERTEX];//当前Vertex集合
int previous[MAX_VERTEX];//前缀
int distances[MAX_VERTEX];//distancevoid printGraph(){//打印图cout<<"-----------begin-------------"<<endl;for(int i = 0; i < MAX_VERTEX; i++){for(int j = 0; j < MAX_VERTEX; j++){if(graph[i][j] < MAX_INT){cout<<graph[i][j]<<"\t";}else{cout<<"∞\t";}}cout<<"\n\v";}cout<<"-----------end-------------"<<endl;
}void printArr(int *arr, int len){//打印数组for(int i = 0; i < len; i++){if(arr[i] >= MAX_INT){cout<<"∞\t";}else{cout<<arr[i]<<"\t";}}cout<<endl;
}void printSituation(){//打印整个结构的各个数据部分。cout<<"[[======================================"<<endl;//cout<<"graph:\n";//printGraph();cout<<"allVertex:\n";printArr(allVertex, MAX_VERTEX);cout<<"emptyVertex:\n";printArr(emptyVertex, MAX_VERTEX);cout<<"previous:\n";printArr(previous, MAX_VERTEX);cout<<"distances:\n";printArr(distances, MAX_VERTEX);cout<<"======================================]]"<<endl;
}void init(){//初始化for(int i = 0; i < MAX_VERTEX; i++){emptyVertex[i] = MAX_INT;allVertex[i] = i;previous[i] = MAX_INT;distances[i] = MAX_INT;for(int j = 0; j < MAX_VERTEX; j++){graph[i][j] = MAX_INT;}}distances[0] = 0;
}void addLine(int start, int end, int weight){//增加一条lineif(start >= MAX_VERTEX || end >= MAX_VERTEX) return;graph[start][end] = weight;if(k == NG){graph[end][start] = weight;}
}void rmLine(int start, int end){//移除一条lineif(start >= MAX_VERTEX || end >= MAX_VERTEX) return;graph[start][end] = MAX_INT;if(k == NG){graph[end][start] = MAX_INT;}
}void dijkstra(){int start = 0;int emptyI = 0;//emptyVertex数组的下标int numHandled = 0;//每次循环都能处理一个vertex,因此需要循环MAX_VERTEX次。while(numHandled < MAX_VERTEX){//1. 把start从allVertex中取出,放入emptyVertex中emptyVertex[emptyI++] = allVertex[start];allVertex[start] = MAX_INT;//2. 找出 已经加入到 empty中的所有点上 的所有的line, 选出其中最短的一条,其end点作为下一次访问的起始点。//3. 根据这些line重新计算distances, 更新distances表--同时更新前缀表,前缀表是随着distances表变化的。int shortestWeight = MAX_INT;int shortestEnd = MIN_INT;for(int j = 0; j < MAX_VERTEX; j++){int currentStart = emptyVertex[j];if(currentStart < MAX_INT){//每一个在empty中的vertex都必须参加比较。在所有的这些vertex中关联的line中选一条 end 值不在empty中的最短的line。for(int i = 0; i < MAX_VERTEX; i++){//i值表示 (currentStart -> i) 这条 line 的 end值if(graph[currentStart][i] >= MAX_INT) {//如果这条line不存在,搜索下一条continue;}else{if(allVertex[i] != MAX_INT && shortestWeight > graph[currentStart][i]){//并且这条line不能是计算过的。如果合法,则比较当前最小的weight。shortestWeight = graph[currentStart][i];//选中这条line。shortestEnd = i;//记住这条line。if(distances[i] >= MAX_INT){//调整distances和previous.distances[i] = graph[currentStart][i] + distances[currentStart];previous[i] = currentStart;}else{if(distances[currentStart] + graph[currentStart][i] < distances[i]){distances[i] = distances[currentStart] + graph[currentStart][i];previous[i] = currentStart;}}}}}}}//4. 把最短的line的end作为新的start重新循环,if(shortestEnd == MIN_INT){cout<<"error!! shortestEnd == MIN_INT"<<endl;}else{cout<<"&&shortest line "<<shortestEnd<<", shortestWeight = "<<shortestWeight<<endl;start = shortestEnd;}//5. numHandled++numHandled++;printSituation();}
}int main(){init();/*addLine(0, 1, 5);addLine(1, 2, 7);addLine(1, 4, 5);addLine(2, 3, 8);addLine(2, 4, 9);addLine(2, 5, 7);addLine(3, 5, 5);addLine(4, 5, 15);addLine(4, 6, 6);addLine(5, 6, 8);addLine(5, 7, 9);addLine(6, 7, 11);*/k = DG;addLine(0, 1, 10);addLine(0, 3, 30);addLine(0, 4, 100);addLine(1, 2, 50);addLine(2, 4, 10);addLine(3, 2, 20);addLine(3, 4, 60);dijkstra();
}
。。。
相关文章:

JDBC数据源连接池(1)---DBCP
何为数据源呢?也就是数据的来源。我在前面的一篇文章《JDBC原生数据库连接》中,采用了mysql数据库,数据来源于mysql,那么mysql就是一种数据源。在实际工作中,除了mysql,往往还会有Oracle,sql se…
如果成为一名高级安卓开发_什么是高级开发人员,我如何成为一名开发人员?
如果成为一名高级安卓开发Becoming a Senior Developer is something many of us strive for as we continue our code journey and build our career. But what does it actually mean to be a "Senior" Developer?成为一名高级开发人员是我们许多人在继续我们的代…

拍牌神器是怎样炼成的(三)---注册全局热键
要想在上海拍牌的超低中标率中把握机会、占得先机,您不仅需要事先准备好最优的竞拍策略,还要制定若干套应急预案,应对不时之需。既定策略交给计算机自动执行,没有问题。可是谁来召唤应急预案呢?使用全局热键应该是个不…

eclipse 变成中文
官方下载 http://www.eclipse.org/babel/downloads.php 按照自己的eclipse版本下载对应的 复制链接 到eclipse ->help->Install New Software 勾选自己的语言包 如: 等待 安装完成 ,无过不好用 更改 右键 属性 更改位置 加后缀 D:\xinle_eclips…

框架模式与设计模式之区别
http://my.oschina.net/u/991183/blog/109854 有很多程序员往往把框架模式和设计模式混淆,认为MVC是一种设计模式。实际上它们完全是不同的概念。框架、设计模式这两个概念总容易被混淆,其实它们之间还是有区别的。框架通常是代码重用,而设计…
村上春树 开始写作_如何克服对写作的恐惧并找到开始的动力
村上春树 开始写作Writing about our work is one of those things that most of us have on our to-do list. But whether its due to procrastination or fear, we never actually get to it. Heres some more motivation and reasons why you should give it a shot!撰写我们…

一个基于组件的动态对象系统
http://hulefei29.iteye.com/blog/1490889 一、静态的痛苦 作为一个项目经验丰富的程序员,你经常会遇到游戏开发过程中的“反复”(iterations):今天美术将一个静态的模型改为骨骼模型并添加了动画;明天企划会议上决定把所有未拾取武器由…

Lua生成Guid(uuid)
全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) 。GUID是一种由算法生成的二进制长度为128位的数字标识符。GUID主要用于在拥有多个节点、多台计算机的网络或系统中。在理想情况下,…

c:if标签的使用
1、标签的基本介绍 <c:if> 标签必须要有test属性,当test中的表达式结果为true时,则会执行本体内容;如果为false,则不会执行。例如:${requestScope.username admin},如果requestScope.username等adm…

ecs和eks 比较_如何使用Kubernetes,EKS和NGINX为网站设置DNS
ecs和eks 比较As the creator of Foo, a platform for website quality monitoring, I recently endeavored in a migration to Kubernetes and EKS (an AWS service).作为网站质量监控平台Foo的创建者,我最近努力迁移到Kubernetes和EKS(一种AWS服务)。 Kubernetes…

仅需6步,教你轻易撕掉app开发框架的神秘面纱(1):确定框架方案
遇到的问题 做游戏的时候用的是cocos2dxlua,游戏开发自有它的一套框架机制。而现在公司主要项目要做android和iOS应用。本文主要介绍如何搭建简单易用的App框架。 如何解决 对于新手来说,接触一门新的知识,往往会思考该怎么入手,…

js全局变量污染
一.定义全局变量命名空间 只创建一个全局变量,并定义该变量为当前应用容器,把其他全局变量追加在该命名空间下 var my{}; my.name{big_name:"zhangsan",small_name:"lisi" }; my.work{school_work:"study",family_work:&q…

cached-query 将缓存和查询数据库高速连接起来的轻类库
介绍 我们经常有这种需求:当我们把memcached增加到项目后我还还要写一个 cacheUtils 或者 cacheManager 之类的类来操作memcached。而且一般的操作不外乎是这种操作: 拿到一段sql,先去memcahed里面看下是否有缓存,假设有就直接返回…

全栈Python Flask教程-建立社交网络
Learn how to build a basic social platform with the Python Flask web framework. 了解如何使用Python Flask网络框架构建基本的社交平台。 In this video, we show you how to:在此视频中,我们向您展示如何: how to create a database, 如何创建数…

py执行系统命令
py执行系统命令 1. os.system In [32]: run os.system("date") Thu Jan 28 09:41:25 CST 2016 In [33]: run Out[33]: 0 只能得到返回值,无法得到输出。 2. os.popen In [35]: run os.popen("date") In [36]: run.read Out[36]: <function…

仅需6步,教你轻易撕掉app开发框架的神秘面纱(2):MVP比MVC更好吗
对于程序框架的选择,由于android天然的MVC,本来不需要另外设计直接使用即可。但是我更加钟情于MVP模式,对于其将ui完全与业务逻辑分离的思路很赞同。 那么什么是业务逻辑?个人认为,对数据(即MVC中的M&…

一、nginx 安装
添加官方 yum 源 1 vim /etc/yum.repos.d/nginx.rep 输入以下内容(OS为你的系统,OSRELEASE 系统版本) 1 [nginx] 2 namenginx repo 3 baseurlhttp://nginx.org/packages/mainline/OS/OSRELEASE/$basearch/ 4 gpgcheck0 5 enabled1 列出可安装…

华为技术面试编码题_最佳技术编码面试准备书
华为技术面试编码题Technical coding interviews are notoriously difficult — almost borderline quiz-like for those unprepared. It can sometimes be a daunting task to navigate all the technical coding preparation resources available online, and one might as…

仅需6步,教你轻易撕掉app开发框架的神秘面纱(3):构造具有个人特色的MVP模式
1. MVP的问题 之前我们说过MVP模式最大的问题在于:每写一个Activity/Fragment需要写4个对应的文件,对于一个简易的app框架来说太麻烦了。所以我们需要对MVP进行一定的简化。 关于MVP模式是什么及其简单实现,可以参照:浅谈 MVP i…

Java进阶之自动拆箱与自动装箱
序. java基本类型介绍 java中,基本数据类型一共有8种,详细信息如下表: 类型大小范围默认值byte8-128 - 1270short16-32768 - 327680int32-2147483648-21474836480long64-9233372036854477808-92333720368544778080float32-3.40292347E38-3.40…

Ceilometer Polling Performance Improvement
Ceilometer的数据采集agent会定期对nova/keystone/neutron/cinder等服务调用其API的获取信息,默认是20秒一次, # Polling interval for pipeline file configuration in seconds.# (integer value)#pipeline_polling_interval 20 这在大规模部署中会对O…

vue使用pwa_如何使用HTML,CSS和JavaScript从头开始构建PWA
vue使用pwaProgressive web apps are a way to bring that native app feeling to a traditional web app. With PWAs we can enhance our website with mobile app features which increase usability and offer a great user experience.渐进式Web应用程序是一种将本地应用程…

仅需6步,教你轻易撕掉app开发框架的神秘面纱(4):网络模块的封装
程序框架确定了,还需要封装网络模块。 一个丰富多彩的APP少不了网络资源的支持,毕竟用户数据要存储,用户之间也要交互,用户行为要统计等等。 使用开源框架 俗话说得好,轮子多了路好走,我们不需要自己造轮…

结构体成员数组不定长如何实现
【目的】 定义一个结构体类,其中的成员变量数组长度不定,根据实例化的对象指定长度,所以想到用指针实现 【现状】 指针可以指向任意长度数组,但结构体类只分配指针本身4字节长度,所以无法扩展 1 /**2 ****************…

团队项目:二次开发
至此,我们有了初步的与人合作经验,接下来投入到更大的团队中去。 也具备了一定的个人能力,能将自己的代码进行测试。接下来尝试在别人已有的基础上进行开发。 上一界51冯美欣同学的项目:http://www.cnblogs.com/maxx/ 1.每个团队从…

arduino 呼吸灯_如何改善您的Arduino呼吸机:用于临时COVID-19呼吸机设计的RTS和SCS简介...
arduino 呼吸灯The world as we know it was recently taken by storm. That storm was the outbreak of the COVID-19 pandemic. This has in turn created a shortage of ventilators world wide which has led many people to foray into the world of ventilator design. 我…

reboot 百度网盘资源
提醒:同志们这是记录,视频文件是加密的,请勿下载 基础班第十三期:http://pan.baidu.com/s/1c2GcvKG 密码: 743j 基础班第十四期链接: http://pan.baidu.com/s/1c24AYa8 密码: x2sh 第十五期: https://pan.baidu.com…

仅需6步,教你轻易撕掉app开发框架的神秘面纱(5):数据持久化
遇到的问题 有的时候程序中需要全局皆可访问的变量,比如:用户是否登录,用户个人信息(用户名,地区,生日),或者一些其他信息如:是否是首次登录,是否需要显示新手引导等等。 其中有些…

响应因特网端口ping命令_如何使用Ping命令识别基本的Internet问题
响应因特网端口ping命令Next time you call your help desk, do you want to wow them with your networking knowledge? Using a command called “ping”, built right into your existing Mac, Windows, or Linux computer, will help identify basic connection problems.…

Android 常见工具类封装
1,MD5工具类: public class MD5Util {public final static String MD5(String s) {char hexDigits[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,a, b, c, d, e, f };try {byte[] btInput s.getBytes();// 获得MD5摘要算法的 MessageDigest 对象MessageDigest md…