您的位置:首页 > 理论基础 > 数据结构算法

经典算法之Floyd算法(求图中任意一对顶点间的最短路径)

2018-01-30 16:47 639 查看
/************************
author's email:wardseptember@gmail.com
date:2018.1.30
************************/
/*
佛洛伊德算法思想:
1)设置两个矩阵A和Path,初始时将图的邻接矩阵赋值给A,将矩阵Path中元素全部设置为-1
2)以顶点k为中间顶点,k取0——n-1(n为图中顶点个位),为图中所有顶点对{i,j}进行如下检测与修改:
如果A[i][j]>A[i][k]+A[k][j],则将A[i][j]改为A[i][k]+A[k][j]的值,将path[i][j]改为k,否则
什么都不做。
佛洛伊德算法的时间复杂度分析:
由算法代码可知,本算法的主要部分是一个三层顺序,取内层循环的操作作为基本操作,则
基本操作的执行次数为n^3,因此时间复杂度为O(n^3)。
*/
#include<iostream>
#define INF 100//INF为比图中任何权值都大的数
#define maxSize 4   //图的顶点数
#define number 8   //图的边数
using namespace std;
typedef struct {//图的定义
int edges[maxSize][maxSize];//邻接矩阵的定义
int n, e;   //分别为顶点数和边数
}MGraph;
MGraph createGraph(MGraph g);
void Floyd(MGraph g, int A[][maxSize],int path[][maxSize]);//佛洛伊德算法
void printPath(int u, int v, int path[][maxSize]);/*递归输出从u到v的最短路径顶点序列*/
int main() {

MGraph g;//定义并初始化图g
g.edges[maxSize][maxSize] = { 0 };
g.n = maxSize; g.e = number;
g = createGraph(g);//创建一个图

int A[maxSize][maxSize] ;
int path[maxSize][maxSize] ;
int u, v;//定义起始点和终点
u = 1,v=0;

Floyd(g, A, path);

cout << "从" << u << "点到" << v << "点的最短路径为:" << endl;
cout << u << " ";
printPath(u, v, path);
cout << v << endl;

cout << "从" << u << "点到" << v << "点的最短路径长度为:" <<A[u][v]<< endl;
system("pause");
return 0;
}

MGraph createGraph(MGraph g) {//此图为一个正方形,按顺时针顺序图的各顶点为0,1,2,3
int i, j;
for (i = 0; i < maxSize; i++)
{
for (j = 0; j < maxSize; j++)
{
g.edges[i][j] = INF;
}
}
g.edges[0][1] = 5;
g.edges[0][3] = 7;
g.edges[2][0] = 3;
g.edges[1][2] = 4;
g.edges[2][1] = 3;
g.edges[2][3] = 2;
g.edges[3][2] = 1;
g.edges[1][3] = 2;
g.n = maxSize;
g.e = number;
return g;
}
void Floyd(MGraph g, int A[][maxSize],int path[][maxSize])
{
int i, j, k;
//对数组A[][]和path[][]进行初始化
for (i = 0; i < g.n; ++i)
{
for (j = 0; j < g.n; ++j)
{
A[i][j] = g.edges[i][j];
path[i][j] = -1;
}
}

/*下面这个三层循环是本算法的主要操作,完成了以k为中间点对所有顶点对{i,j}
进行检测和修改*/
for (k = 0; k < g.n; ++k)
{
for (i = 0; i < g.n; ++i)
{
for (j = 0; j < g.n; ++j)
{
if (A[i][j] >( A[i][k] + A[k][j]))
{
A[i][j] = A[i][k] + A[k][j];
path[i][j] = k;
}
}
}
}
}
void printPath(int u, int v, int path[][maxSize])	/*递归输出从u到v的最短路径顶点序列*/
{
if (path[u][v] == -1)
return;
else
{
cout<< path[u][v] << " ";
int mid = path[u][v];
printPath(u, mid, path);//处理mid前半段路径
printPath(mid, v, path);//处理mid后半段路径
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐