弗洛伊德算法(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. 开源Webshell利用工具——Altman

    开源Webshell利用工具--Altman keepwn @ 工具 2014-06-04 共 6114 人围观,发现 43 个不明物体收藏该文 Altman,the webshell tool,自己 ...

  2. SpringMVC找不到对应的页面

    确认springmvc配置文件视图解析器配置正确. <!-- 视图解析器 --> <bean class="org.springframework.web.servlet. ...

  3. Maven 高级应用

    Maven 的高级应用主要体现在 ==依赖==,==聚合==,==继承== * 依赖 就是在当前项目的pom.xml 总引入依赖的坐标 最最经常用到的 <dependencies> < ...

  4. iOS笔记,开发经验总结【持续更新】

    1. 设置navigationBar 背景颜色有色差, 原因:如果单纯的设置背景颜色也是有高斯模糊处理的效果,对纯色高斯模糊处理过后相当于纯色的70%(猜测)透明化处理,但是反正就是有色差 解决方法一 ...

  5. layDay日期格式不合法报错解决

    报错内容如下: Uncaught TypeError: Cannot read property 'appendChild' of undefined 相关报错内容的行代码如下 即使日期格式拼接正确也 ...

  6. redis 安装 配置 及启动

    linux下安装redis及其中遇到的问题的解决方法1.将下载好的压缩包放到/usr/local目录下# tar xzf redis-3.0.2.tar.gz# cd redis-3.0.2# mak ...

  7. 闲来无事做了一个项目,内有redis,EasyUI样式简单应用,七层分页查询,API跨域。

    <link href="~/jquery-easyui-1.5.3/themes/default/easyui.css" rel="stylesheet" ...

  8. NIO流—理解Buffer、Channel概念和NIO的读写操作

    NIO流与IO流的区别 面向流与面向块 IO流是每次处理一个或多个字节,效率很慢(字符流处理的也是字节,只是对字节进行编码和解码处理). NIO流是以数据块为单位来处理,缓冲区就是用于读写的数据块.缓 ...

  9. 1015 德才论(sort、结构体vector)

    题目: 宋代史学家司马光在<资治通鉴>中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人.凡取人之术,苟不得圣人,君子而与之,与其得小人,不 ...

  10. python散记

    1.AOP 将不同的类的内部中雷同的代码和重复的功能,提取出来以重用. 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等 2.新式类,经典类 新式类 ...