弗洛伊德算法(Floyed-Warshall)

适用范围及时间复杂度

该算法的时间复杂度为O(N^3),适用于出现负边权的情况。

可以求取最短路径或判断路径是否连通。可用于求最小环,比较两点之间的大小。

(什么??你不知道什么是负边权??戳->http://t.cn/Ef7pbu6)

核心思想

对于任意一个K点,i到j的距离有两种可能:要么经过k点,要么不经过k点。所以我们只需要不断的迭代k,比较d[i][k]与d[i][k]+d[k][j]的值。如果后者更短,则更新d[i][k]的值。如此重复,最后检查完所有的k时,我们便得到了最短距离。

注意事项及常见问题

由核心思想不难看出,这个算法需要三层循环来实现。但k的位置是值得注意的。经过分析不难发现,k属于最外层循环。

i,j,k三点并不能相同。如若相同,则算法无意义。(自己到自己的距离当然是零啦)

在使用算法时,将map[i][j]值初始为最大/小,map[i][i]一定设置为0(自己到自己当然是零啦)

有时题目会暗含重复数据,也就是相同的路径权重不同。所以要根据题目进行数据比较,更新最大/小的值。

代码实现

初始化:如若两点(假定两点为u,v)相连,则其最短路径初始化为权重。如不相连则初始化为巨大值(0x7ffffff)

 if(w[u][v]){
dis[u][v]=w[u][v];
}else{
dis[u][v]=*7ffffff;
}

戳开查看

step2:寻找中间点K,比较距离并判断是否更新。

 for(int k=;k<=n;k++){
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
if(i!=k&&i!=j&&j!=k){
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
}

戳开查看

迪杰斯特拉算法(dijkstra)

适用范围及时间复杂度

单源路径算法,只计算起点只有一个的情况。不可以用于处理存在负边权的情况。时间复杂度O(N^2)

多用于计算一个结点到其他所有结点的最短路径。以起始点为中心向外层扩展,直到扩展到终点为止。

核心思想

对于图中一个点G(V,E),可以被归为以下两组集合之一:

■白点集合:指已确定最短路径的顶点集合。用S表示,初始时S中只有一个元素,即源点,以后每求得一条最短路径,就加入到集合S中,直到全部顶点都加入S中,算法就结束了。

■蓝点集合:指未确定最短路径的顶点集合。用U表示,按最短路径长度的递增次序把第二组的顶点加入到S中。在加入过程中,总是寻找到与起点距离最短的先加入,保持集合S中的路径长度永远比集合U中的小。
用vis[v]标记顶点v是白点还是蓝点,白点用vis[v]=true标记,蓝点用vis[v]=false标记。很显然,初始化时,所有vis除源点为true外,其它均为false;

第1轮循环找到dis[1]最小,将1变成白点。对所有与之相连的蓝点做出改,使得:dis[2]=2;dis[3]=4;dis[4]=7;此时dis[2],dis[3],dis[4]被它最后一个中转点修改了最短路径。

第2轮循环找到dis[2]最小,将2变成白点。对所有与之相连的蓝点做出修改,使得:dis[3]=3;dis[5]=4;此时,dis[3],dis[5]被它最后一个中转点修改了最短路径

第3轮循环找到dis[3]最小,将3变为白点。对所有与之相连的蓝点做出修改,使得:dis[4]=4,而dis[5]之前已经计算出来等于4了,现在不能用9去修改。说明点3不是5的最后一个中转点。此时dis[4]被它最后一个中转点修改了最短路径。
第4轮循环找到dis[4]最小,将4变成白点。但点4没有与之相连的蓝点,故不需要做出修改。
第5轮循环找到dis[5]最小,把5置为白点,而已经没有与5相连接的蓝点。故无须更改。
如此过后,便得到了起点至各点的单源最短路径。

代码实现

我们至少需要三个数组来存储数据(邻接矩阵法)。暂定map[][]为邻接矩阵,s为起点,e为终点,dis[i]表示i点到源点的最短路径。bool vis[]表示该点为蓝点或白点。

初始化

 for(int i=;i<=n;i++)
for(int j=;j<=n;j++) g[i][j]=maxx;
for(int i=;i<=n;i++) dis[i]=map[s][i]; //为dis赋初值
vis[s]=true; //起点标记为已访问
dis[s]=; //起点标记为白点

算法核心

     for(int i=;i<=n-;i++){
minx=maxx;
for(int j=;j<=n;j++)
if(!vis[j]&&dis[j]<minx){
minx=dis[j]; //不断寻找dis的最小值,并把坐标保存在u中
u=j;
}
if(u==) break; //没找到蓝点,退出循环
vis[u]=true; //把找到的蓝点值为已访问
for(int v=;v<=n;v++)
//如果j到起点的最短路径大于k到起点的最短路径+k到j的距离,则更新dis[j]
dis[v]=min(dis[v],dis[v]+map[u][v]);
}
printf("%.2lf\n",dis[t]);

注意事项

dijskstra算法有两重循环,第一重循环是1到n-1,第二重循环是1到n。这中间可以优化的是,如果在接收数据的时候,保存最大的点p,这样,第一重循环就只需要扫描到p-1,而第二重循环只需要扫描到p。降低了时间复杂度。但多数时候,题目是给定了最大的点,不需要再找了。

 for(int i=;i<=n;i++){
scanf("%d%d%d",&u,&v,&w);
if(g[u][v]>w) g[u][v]=g[v][u]=w;
p=max(p,max(u,v));
}

队列优化

priority_queue< pair<int,int> > q;
void Dijkstra()
{
memset(Distrance,0x3f,sizeof(Distrance));
Distrance[]=;
q.push(make_pair(,));
while(q.size())
{
int x=q.top().second;
q.pop();
if(Vist[x])
continue;
Vist[x]=true;
for(int i=Head[x]; i; i=Edges[i].Next)
{
int y=Edges[i].End;int z=Edges[i].Val;
if(Distrance[y]>Distrance[x]+z)
{
Distrance[y]=Distrance[x]+z;
q.push(make_pair(-Distrance[y],y));
}
}
}
}

最短路径算法(I)的更多相关文章

  1. Johnson 全源最短路径算法

    解决单源最短路径问题(Single Source Shortest Paths Problem)的算法包括: Dijkstra 单源最短路径算法:时间复杂度为 O(E + VlogV),要求权值非负: ...

  2. Floyd-Warshall 全源最短路径算法

    Floyd-Warshall 算法采用动态规划方案来解决在一个有向图 G = (V, E) 上每对顶点间的最短路径问题,即全源最短路径问题(All-Pairs Shortest Paths Probl ...

  3. Dijkstra 单源最短路径算法

    Dijkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家 Edsger Dijkstra 于 1956 年 ...

  4. Bellman-Ford 单源最短路径算法

    Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法.该算法由 Richard Bellman 和 Leste ...

  5. 几大最短路径算法比较(Floyd & Dijkstra & Bellman-Ford & SPFA)

    几个最短路径算法的比较:Floyd 求多源.无负权边(此处错误?应该可以有负权边)的最短路.用矩阵记录图.时效性较差,时间复杂度O(V^3).       Floyd-Warshall算法(Floyd ...

  6. 带权图的最短路径算法(Dijkstra)实现

    一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...

  7. 无向图的最短路径算法JAVA实现

    一,问题描述 给出一个无向图,指定无向图中某个顶点作为源点.求出图中所有顶点到源点的最短路径. 无向图的最短路径其实是源点到该顶点的最少边的数目. 本文假设图的信息保存在文件中,通过读取文件来构造图. ...

  8. 最短路径算法之Dijkstra算法(java实现)

    前言 Dijkstra算法是最短路径算法中为人熟知的一种,是单起点全路径算法.该算法被称为是“贪心算法”的成功典范.本文接下来将尝试以最通俗的语言来介绍这个伟大的算法,并赋予java实现代码. 一.知 ...

  9. Floyd最短路径算法

    看完这篇文章写的小程序,Floyd最短路径算法,求从一个点到另一个点的最短距离,中间可以经过其他任意个点.三个for循环,从i到j依次经过k的最短距离,最外层for循环是经过点K,内部两个循环是从i( ...

  10. 最短路径算法(Dijkstra算法、Floyd-Warshall算法)

    最短路径算法具体的形式包括: 确定起点的最短路径问题:即已知起始结点,求最短路径的问题.适合使用Dijkstra算法. 确定终点的最短路径问题:即已知终结结点,求最短路径的问题.在无向图中,该问题与确 ...

随机推荐

  1. nRF5 SDK for Mesh(八) Exploring Mesh APIs using light switch example,使用 灯开关 案例探索BLE mesh 的APIS

    Exploring Mesh APIs using light switch example The light switch example is meant to showcase the API ...

  2. java中的序列化问题

    序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,将数据分解成字节流,以便存储在文件中或在网络上传输.可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间.序列化是 ...

  3. ASP.NET Core AD 域登录 (转载)

    在选择AD登录时,其实可以直接选择 Windows 授权,不过因为有些网站需要的是LDAP获取信息进行授权,而非直接依赖Web Server自带的Windows 授权功能. 当然如果使用的是Azure ...

  4. Redis基本讲解

    Redis基本讲解 首先我们要了解redis的使用试用范围,redis不像数据库能建立关系型的数据结构,除了有序集合能关联一个double类型的分数其它的几种都是单一存储的,所以他的局限性就比较高了, ...

  5. 01 Oracle分区索引

    Oracle分区索引   索引与表类似,也可以分区: 分区索引分为两类: Locally partitioned index(局部分区索引) Globally partitioned index(全局 ...

  6. 使用Mybatis连接到Mysql报错,WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be esta

    在Eclipse中使用springboot整合Mybatis,连接到5.7版本Mysql报错WARN: Establishing SSL connection without server's ide ...

  7. 非空校验在oracle和mysql中的用法

    oracle判断是否为null nvl(参数1,参数2) :如果参数1为null则返回参数2,否则返回参数1 mysql判断是否为null ifnull(参数1,参数2) :如果参数1为null则返回 ...

  8. easyui图标

    只要在icons属性上,加上图标对应的名字,easyUI就会显示对应的图标,这些图标都是easyui内置的.

  9. SVN(独立安装)-1.9.7 centos 6.5(64位)

    说明: 运行方式: 基于Apache的http.https网页访问形式: 基于svnserve的独立服务器模式. 数据存储方式: 在Berkeley DB数据库中存储数据: 使用普通的文件FSFS存储 ...

  10. Python学习 :面向对象(一)

    面向对象 一.定义 面向对象:面向对象为类和对象之间的应用 class + 类名: #在类中的函数称作 “方法“ def + 方法名(self,arg): #方法中第一个参数必须是 self prin ...