考研最路径dijkstra和floyd
先来讲个段子:为什么 Dijkstra 不能提出 floyd 算法?因为他的名字是 ijk 而不是 kij。
get不到点没有关系。我们今天的任务是看懂这个笑话。
dijkstra 的效率是n^2.处理的是一个点到所有点的最短路径。而floyd效率n^3,处理的是任意点的最短距离。dijkstra如果要处理任意点。
Dijkstra单源最短路算法(无法解决带负边问题):
单源就是由一到多,或由多到一,就是起点和终点至少有一个为一,若均大于1则为多源,求多源最短路时使用Dijkstra算法需要进行多次操作。
普通:
图的建立(就是把输入的路线储存起来):用邻接矩阵。
首先要进行初始化,将每个点到起点的距离设为一个较大的数,并将所有的点都标记为未访问过。
就是由起点开始,标记起点已经访问过,并将起点到起点的距离更新为0,遍历每一个可以走到的点,更新他们到起点的距离,然后找出未访问过的距离起点最近的点,因为它已经是为访问过的点中最近的点,所以从别的点来到这一点一定会比现在要远,所以它此时已经是最近的点了,然后再把它看作是出发点,再次进行上述操作(在更新距离是要先判断新距离是否比久距离要来得近,若比原来的远则不更新距离),最后没有未访问过的点或剩余点到出发点的距离均为无穷远则结束操作。
在更新距离时可以顺便更新前驱,就能够记录路径,不过一般题目都会有多条路径,在记录时要注意题目要求。
时间复杂度:O(n^2) ,因为要先对每个节点进行遍历,更新路径,然后还要找出所有未访问节点中最近的点,最差的情况就是要将n个点均进行操作,操作次数就是(2n)*n。
优先队列优化(堆优化):
优化主要就是缩短了查找未被访问的节点中最近的节点的时间,用优先队列来完成。
从起点出发遍历所有点,若距离缩短则将其加入队列中,结束后队列首则为下一点。当队列首元素中保存的点和存入时的距离大于此时该点对应距离时,将其跳过。
Floyd多源最短路径算法(无法解决带负边问题):
有一些动态规划的思想,利用中介点。dist[i][j] = min(dist[i][k]+dist[k][j],dist[i][j]);
当有下一点l 作为中介点时,A到B的距离就有五种种选择设上一中介点为C 这一中介点为D。A-B \ A-C-B \ A-D-B \ A-D-C-B \ A-C-D-B 。而D-C-B和A-C-D在上次以C为中介点就已经算出,D-B = min(D-C-B,D,B),A-C-D同理,然后就是不断的重复,把所有点做中介点一次就完成了。
核心代码:
for(int k=1;k<=n;i++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
dist[i][j] = min(dist[i][k]+dist[k][j],dist[i][j]);
}
}
}
int dijkstra(Mgraph g,int path[],int dis[],int v)
{
int set[maxSize];
for(int i=0;i<g.n;i++)
{
set[i]=0;
dis[i]=g.edge[v][i];
if(g.edge[v][i]<inf)
path[i]=v;
else
path[i]=-1; }
set[v]=1;
path[v]=-1;
for(int i=0;i<g.n-1;i++)
{
int k=-1,min=inf;
for(int j=0;j<g.n;j++)
{
if(dis[j]<min&&set[j]==0)
{
min=dis[j];
k=j;
}
}
set[k]=1;
for(int j=0;j<g.n;j++)
{
if(set[j]==0&&dis[j]>dis[k]+g.edge[k][j])
{
dis[j]=dis[k]+g.edge[k][j];
path[j]=k;
}
} } }
void printPath(int u,int path[])
{
int stack[maxSize];
int top=-1;
while(path[u]!=-1)
{
stack[++top]=u;//这个是是u不是path[u],终点也要进来。
u=path[u];
}
stack[++top]=u;//最后一个==-1的点
while(top!=-1)
{
cout<<stack[top--]<<" ";
cout<<endl;
}
}
void floyd(Mgraph g,int path[][maxSize])
{
int map[maxSize][maxSize];
for(int i=0;i<g.n;i++)
for(int j=0;j<g.n;j++)
{
map[i][j]=g.edge[i][j];
path[i][j]=-1;
}
for(int k=0;k<g.n;k++)
for(int i=0;i<g.n;i++)
for(int j=0;j<g.n;j++)
{
if(map[i][j]>map[i][k]+map[k][j])
{
map[i][j]=map[i][k]+map[k][j];
path[i][j]=k;
} }
}
void printfpath(int u,int v,int path[][maxSize])
{
if(path[u][v]==-1)
cout<<u<<"——"<<v<<" ";
else
{
int mid=path[u][v];
printfpath(u,mid,path);
printfpath(mid,v,path);
}
}

这就是为什么folyd为什么是kij的循环。
考研最路径dijkstra和floyd的更多相关文章
- (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍
这一篇博客以一些OJ上的题目为载体.整理一下最短路径算法.会陆续的更新... 一.多源最短路算法--floyd算法 floyd算法主要用于求随意两点间的最短路径.也成最短最短路径问题. 核心代码: / ...
- 最短路(Dijkstra,Floyd,Bellman_Ford,SPFA)
当然,这篇文章是借鉴大佬的... 最短路算法大约来说就是有4种——Dijkstra,Floyd,Bellman_Ford,SPFA 接下来,就可以一一看一下... 1.Dijkstra(权值非负,适用 ...
- 算法学习笔记(三) 最短路 Dijkstra 和 Floyd 算法
图论中一个经典问题就是求最短路.最为基础和最为经典的算法莫过于 Dijkstra 和 Floyd 算法,一个是贪心算法,一个是动态规划.这也是算法中的两大经典代表.用一个简单图在纸上一步一步演算,也是 ...
- ACM学习之路___HDU 1385(带路径保存的 Floyd)
Description These are N cities in Spring country. Between each pair of cities there may be one trans ...
- 最短路 dijkstra and floyd
二:最短路算法分析报告 背景 最短路问题(short-path problem):若网络中的每条边都有一个数值(长度.成本.时间等),则找出两节点(通常是源节点和阱节点)之间总权和最小的路径就是最短路 ...
- 最短路知识点总结(Dijkstra,Floyd,SPFA,Bellman-Ford)
Dijkstra算法: 解决的问题: 带权重的有向图上单源最短路径问题.且权重都为非负值.如果采用的实现方法合适,Dijkstra运行时间要低于Bellman-Ford算法. 思路: 如果存在一条从i ...
- Algorithm --> Dijkstra和Floyd最短路径算法
Dijkstra算法 一.最短路径的最优子结构性质 该性质描述为:如果P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中间顶点,那么P(k,s)必 ...
- 求最短路径的三种算法: Ford, Dijkstra和Floyd
Bellman-Ford算法 Bellman-Ford是一种容易理解的单源最短路径算法, Bellman-Ford算法需要两个数组进行辅助: dis[i]: 存储顶点i到源点已知最短路径 path[i ...
- 最短路算法详解(Dijkstra,Floyd)
最短路径 在一个无权的图中,若从一个顶点到另一个顶点存在着一条路径,则称该路径长度为该路径上所经过的边的数目,它等于该路径上的顶点数减1.由于从一个顶点到另一个顶点可能存在着多条路径,每条路径上所经过 ...
随机推荐
- LocalDateTime、OffsetDateTime、ZonedDateTime互转,这一篇绝对喂饱你
前言 你好,我是A哥(YourBatman). 在JSR 310日期时间体系了,一共有三个API可用于表示日期时间: LocalDateTime:本地日期时间 OffsetDateTime:带偏移量的 ...
- html简单基础
标签语法 标签的语法: <标签名 属性1="属性值1" 属性2="属性值2"-->内容部分</标签名> <标签名 属性1=&quo ...
- 云原生流水线 Argo Workflow 的安装、使用以及个人体验
注意:这篇文章并不是一篇入门教程,学习 Argo Workflow 请移步官方文档 Argo Documentation Argo Workflow 是一个云原生工作流引擎,专注于编排并行任务.它的特 ...
- java虚拟机入门(一)-jvm基础
转行学java之前,总是听着大佬们说着java像个渣男一样可以跨平台,一次编译到处运行,瞬间,我就坚定了学java的信念,哎呀妈呀,得劲.真的学java之后,好像渣男也不是那么好学的,尤其这货的必杀技 ...
- Webpack4.0各个击破(8)tapable篇
目录 一. tapable概述 二. tapable-0.2源码解析 2.1 代码结构 2.2 事件监听方法 2.3 事件触发方法 三. tapable1.0概述 一. tapable概述 tapab ...
- 代理模式详解:静态代理+JDK/CGLIB 动态代理实战
1. 代理模式 代理模式是一种比较好的理解的设计模式.简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标 ...
- 深度学习论文翻译解析(十八):MobileNetV2: Inverted Residuals and Linear Bottlenecks
论文标题:MobileNetV2: Inverted Residuals and Linear Bottlenecks 论文作者:Mark Sandler Andrew Howard Menglong ...
- 基于navicat的数据库导入导出
1.右键当前数据库,选择转储SQL文件 选择导出sql的存放路径 2.新建统一命名的数据库,右键运行SQL文件 3,.选择要导入的SQL文件后如图
- Phoenix踩坑填坑记录
Phoenix踩坑填坑记录 Phoenix建表语句 如何添加二级索引 判断某表是否存在 判断索引是否存在 Date类型日期,条件判断 杂项 记录Phoenix开发过程中的填坑记录. 部分原文地址:ph ...
- 浅聊ARP
今天借用思科公司的Cisco Packet Tracer Student这款软件浅聊ARP 什么是ARP? ARP即地址解析协议(Address Resolution Protocol),是根据Ip地 ...