图论之最短路径(1)——Floyd Warshall & Dijkstra算法
开始图论学习的第二部分:最短路径。
由于知识储备还不充足,暂时不使用邻接表的方法来计算。
最短路径主要分为两部分:多源最短路径和单源最短路径问题
多源最短路径:
介绍最简单的Floyd Warshall算法:
思路如下:把所有从顶点i到j可能经过的顶点一一枚举,不断更新从i到j的最小权值:d[i][j] = min{d[i][j],d[i][k]+d[k][j]},是一种动规的思想
局限性:不能处理有负权回路(负圈)的情况,而且一般是使用邻接矩阵的方式来实现。
优劣性:思路简单,核心代码简洁易懂,但是时间复杂度为O(N^3)效率较差,适合处理小范围数据。
核心代码只有5行:
for (int k = 1; k <= n; k++)
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
if (e[i][j]>e[i][k] + e[k][j])
e[i][j] = [i][k] + e[k][j];
在情况不是特别复杂的情况下也可以用来求解单源最短路径问题
单源最短路径:
先介绍简单的Dijkstra算法
核心思路:假设计算从顶点1到其余各顶点的最短路径。先用一个一维数组dis储存1号顶点到其余各顶点的初始路程(这时每个值被称为估计值),找到一个离1的距离最小的顶点,比如2,那么dis[2]的值就成为确定值(因为顶点1到其它顶点的距离都更长,所以从其他顶点中转肯定没有直接从1走到2短,那么这个值就是1到2的最短路径)。现在我们有了一个确定值dis[2],就开始利用这个值尝试去更新1到其他顶点的最短距离(说白了就是都从2绕一下试试),更新完成后我们就不再管顶点2,从顶点3开始再搜索一个到1距离最短的点(这时候用的是已经更新过的值),不断重复上述的过程,直到所有的估计值都变成确定值。
局限性:不能应对有负权边的情况
优化:当边数较少时(稀疏图),使用邻接表效率会比邻接矩阵更高(后续会给出,这里先用邻接矩阵写)
要注意的是:我们使用两个集合P和Q来区别已经确定的顶点和待确定的顶点(用book数组来标记)
整体代码如下:(求顶点1到其他顶点的最短路径)
/*Dijkstra算法用邻接矩阵实现,求一号顶点到其他各顶点的最短路径*/
# include<iostream> using namespace std; int dis[],book[];//dis数组存放估计值,最后变为确定值。book数组用于标记顶点是否被处理过 int e[][];//邻接矩阵 const int INF = ;//INF用于表示正无穷 int main()
{
int n, m;//n为顶点数目,m为边的数目
int t1, t2, t3;
int temp; //初始化邻接矩阵:
for (int i = ; i <= ; i++)
for (int j = ; j <= ; j++)
{
if (i == j)
e[i][j] = ;
else
e[i][j] = INF;
} //读入边:
for (int i = ; i < m; i++)
{
cin >> t1 >> t2 >> t3;//表示从顶点t1到顶点t2有一条权为t3的边
e[t1][t2] = t3;//这里是有向图
} //初始化dis数组:
for (int i = ; i <= n; i++)
dis[i] = e[][i]; //初始化book数组,说明dis[1]已经是确定值了
book[] = ; //Dijkstra算法核心:
for (int i = ; i < n; i++)//只用执行n-1次,最后一个点一定是确定的
{
//第一步:找到现在距离顶点1最近的点
int min = INF;
for (int j = ; j <= n; j++)
{
if (book[j] == && dis[j] < min)
{
min = dis[j];
temp = j;//记录
} book[temp] = ; for (int i = ; i <= n; i++)
{
if (e[temp][i] < INF)
{
if (dis[i]>dis[temp] + e[temp][i])
dis[i] = dis[temp] + e[temp][i];
}
}
}
} //输出:
for (int i = ; i <= n; i++)
cout << dis[i] << " "; //system("pause"); return ;
}
图论之最短路径(1)——Floyd Warshall & Dijkstra算法的更多相关文章
- 图论——最短路:Floyd,Dijkstra,Bellman-Ford,SPFA算法及最小环问题
一.Floyd算法 用于计算任意两个节点之间的最短路径. 参考了five20的博客 Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个 ...
- 最短路径 - 迪杰斯特拉(Dijkstra)算法
对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点为源点,最后一个顶点为终点.最短路径的算法主要有迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd ...
- 图的最短路径---迪杰斯特拉(Dijkstra)算法浅析
什么是最短路径 在网图和非网图中,最短路径的含义是不一样的.对于非网图没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径. 对于网图,最短路径就是指两顶点之间经过的边上权值之和最 ...
- 最短路径-迪杰斯特拉(dijkstra)算法及优化详解
简介: dijkstra算法解决图论中源点到任意一点的最短路径. 算法思想: 算法特点: dijkstra算法解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树.该算法常用于路由算 ...
- 数据结构(C#):图的最短路径问题、(Dijkstra算法)
今天曾洋老师教了有关于图的最短路径问题,现在对例子进行一个自己的理解和整理: 题目: 要求:变成计算出给出结点V1到结点V8的最短路径 答: 首先呢,我会先通过图先把从V1到V8的各种路径全部计算下来 ...
- 最短路径(floyd和Dijkstra)
最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- 图论之最短路径(2)——Bellman-Ford算法
继续最短路径!说说Bellman—Ford算法 思路:假设起点为s,图中有n个顶点和m个边,那么它到任一点(比如i)的最短路径 最多可以有n-1条(没有回路就是n-1条):因为最短路径中不可能包含回路 ...
- 最短路径问题 HDU - 3790 (Dijkstra算法 + 双重权值)
参考:https://www.cnblogs.com/qiufeihai/archive/2012/03/15/2398455.html 最短路径问题 Time Limit: 2000/1000 MS ...
- 图论篇3——最短路径 Dijkstra算法、Floyd算法
最短路径 问题背景:地图上有很多个城市,已知各城市之间距离(或者是所需时间,后面都用距离了),一般问题无外乎就是以下几个: 从某城市到其余所有城市的最短距离[单源最短路径] 所有城市之间相互的最短距离 ...
随机推荐
- Nginx下轻松开启Drupal简洁链接
大家都知道Drupal在apache环境下使用简洁链接是件很轻松的事,因为官方已经把写好的.htaccess文件附在源代码里,一般在配置里直接就可以打开了.但在Nginx下却没有那么简单,但不用担心, ...
- 关于一致性Hash算法
在大型web应用中,缓存可算是当今的一个标准开发配置了.在大规模的缓存应用中,应运而生了分布式缓存系统.分布式缓存系统的基本原理,大家也有所耳闻.key-value如何均匀的分散到集群中?说到此,最常 ...
- mvn 仓库地址修改
默认仓库的存储位置 Maven缺省的本地仓库路径为${user.home}/.m2/repository具体如下图 自定义修改仓库的存储位置: 可改变默认的 .m2 目录下的默认本地存储库文件夹通过修 ...
- win7/win8下手工搭建WAMP环境
win7/win8下手工搭建WAMP环境. 最近学习wamp,看了好多教程,出来好多问题,终于成功搞定,这里集合了一下最好的教程,写了一些自己的经验,希望大家有用 这里不能上传图片,我就写了个带pdf ...
- SQLSERVER2008中创建数据库发生无法获得数据库'model'上的排他锁
SQLSERVER2005中创建数据库发生无法获得数据库'model'上的排他锁是怎么回事? 创建数据库失败,提示无法获得数据库‘model’上的排他锁,如下图所示: 解决方法: 在查询分析器中运行如 ...
- 关于HFile的存储结构梳理以及快速定位rowkey
转自:http://blog.csdn.net/yangbutao/article/details/8394149 了解了布隆过滤器作用于HFile之上以及对HFile有了更深层次了解. 另有:htt ...
- 3D MAX 人物骨骼建设
3DMax方面所涉及的专业知识: (1)一下的关于3DMax中对于人物的设计和操作均需要在对3DMax基础知识熟练掌握的情况下进行的. (2)骨骼架设: ...
- 什么是事务(transaction)?它有什么好处
为了完成对数据的操作,企业应用经常要求并发访问在多个构件之间共享的数据.这些应用在下列条件下应该维护数据的完整性(由应用的商务规则来定义): 分布式访问一个单独的数据资源,以及从一个单独的应用构件访问 ...
- 调整swap分区大小-Linux下安装Oracle时报swap不够解决方法
调整swap分区大小 方法一:如果磁盘有剩余的空间,用分区工具新建一个swap分区.并写到/etc/fstab里面.再 #swapon -a方法二:可以用一个文件做交换分区. su root cd / ...
- Oracle过程及函数的参数模式详解
一.In.out.in out模式 在Oracle中过程与函数都可以有参数,参数的类型可以指定为in.out.in out三种模式. 三种参数的具体说明,如下图所示: (1)in模式 in模式是引用传 ...