算法基础 - 多源点最短路径(Floyd算法)
2016-05-11 02:27
465 查看
Floyd算法
Floyd算法又称为插点法,是一种用于寻找给定的加权图中多源点之间最短路径的算法。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。思路
路径矩阵
通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。从图的带权邻接矩阵
A=[a(i,j)] n×n开始,递归地进行
n次更新,即由矩阵
D(0)=A,按一个公式,构造出矩阵
D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。
引用自:百度百科
采用松弛技术(松弛操作),对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为
O(n^3);
状态转移方程
其状态转移方程如下:map[i,j]:=min{map[i,k]+map[k,j],map[i,j]};
map[i,j]表示i到j的最短距离,
K是穷举
i,j的断点,
map[n,n]初值应该为0,或者按照题目意思来做。
当然,如果这条路没有通的话,还必须特殊处理,比如没有
map[i,k]这条路。
其实就是枚举第三个点,看是否能出现
1->3->2的距离比
1->2的短
复杂度
时间复杂度: O(N^3);空间复杂度:O(N^2);
伪代码
For k:=1 to n For i:=1 to n For j:=1 to n If D[i,j]>D[i,k]+D[k,j] Then D[i,j]:=D[i,k]+D[k,j];
代码实现
// // main.cpp // HiHocoder // // Created by Alps on 16/5/9. // Copyright © 2016年 chen. All rights reserved. // #include <iostream> #include <cstring> #include <string> using namespace std; long long dist[102][102]; //表示最大节点数是101个 long long minNum(long long a, long long b){ if(a == -1) return b; return a < b ? a : b; } void floyd(long long dist[][102], int N){ for(int i = 1; i <= N; i++){ for(int j = 1; j <= N; j++){ for(int k = 1; k <= N; k++){ if(dist[j][i] == -1 || dist[i][k] == -1){ continue;//如果没路径别走 } dist[j][k] = minNum(dist[j][k], dist[j][i]+dist[i][k]); } } } } int main(){ int N,M; while(cin>>N>>M){ for(int i = 0; i <= N; i++){ for(int j = 0; j <= N; j++){ dist[i][j] = -1; //初始化为-1 表示无穷远 if(i == j){ dist[i][j] = 0; } } } int x, y, d; for(int i = 0; i < M; i++){ cin>>x>>y>>d; dist[x][y] = minNum(dist[x][y], d); dist[y][x] = dist[x][y];//无向图,如果是有向图去掉这个路径 } floyd(dist, N); for(int i = 1; i <= N; i++){ //输出整个矩阵 for(int j = 1; j<= N; j++){ cout<<dist[i][j]<<" "; } cout<<endl; } } return 0; }
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析