您的位置:首页 > 其它

最短路径算法设计与实现(Dijkstra算法和Floyd算法)

2016-01-14 20:16 811 查看

1.问题描述和需求分析

随着计算机、网络、Android的兴起与发展,人们在出行时越来越离不开计算机的帮助。人们在旅行时越来越需要地图的帮助。在人们查找最佳行程路线时,便涉及了最短路径问题。用户想从A地到B地,如何查找最短路径,最快到达;以及如何在一组地点中找到相互间的最短路径。这其实便是最短路径算法解决的问题。

本文便是围绕最短路径问题,设计并实现Dijstra和Floyd算法。

2. 算法介绍

2.1 Dijkstra算法

Dijkstra算法又称为单源最短路径,所谓单源是在一个有向图中,从一个顶点出发,求该顶点至所有可到达顶点的最短路径问题。

1) 算法思想

设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

2)算法步骤

①初始时,S只包含源点,即S={v},v的距离为0。U包含除v外的其他顶点,即:U={其余顶点},若v与U中顶点u有边,则

2.2 Floyd算法

Floyd算法是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包。

1)算法思想

Floyd算法是典型的动态规划算法,其思想如下:

从任意节点i到任意节点j的最短路径仅仅只有2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。

2).算法步骤

①从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。

②对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是,更新它。

3.程序设计

3.1 图的数据结构

为了方便存储图的顶点信息和路径权值, 图的权值采用邻接矩阵的形式来存储。

设计数据结构如下:

typedef struct _Graph
{
int     arrArcs[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT];    // 邻接矩阵
int     nVertexCount;                               // 顶点数量
int     nArcCount;                                  // 边的数量
} Graph;


3.2 图的数据录入函数

为了方便录入,设计两种录入方式,一种为手动邻接矩阵值信息,一种是设定最大权值,自动生成随机数来生成邻接矩阵。

数据录入模块封装为一个函数,其实现如下:

/************************************************************************/
/* 图数据录入算法:根据命令行提示将邻接矩阵存储到图Graph中
录入方式有两种,自动生成和手动录入
*/
/*
参数:
Graph *pGraph       图数据结构
*/
/************************************************************************/

void StoreGraphData( Graph *pGraph )
{
cout << "算法采用邻接矩阵来存储图的相关数据,因此请按指示输入数据" << endl;
cout << "请输入顶点数量(最多50个顶点): ";
cin >> pGraph->nVertexCount;
cout << "请输入边的数量: ";
cin >> pGraph->nArcCount;
cout << endl << "自动生成邻接矩阵请输入1,手动输入邻接矩阵请输入0:" ;
int nWay = 1;
cin >> nWay;
if ( 1 == nWay) // 自动生成
{
cout << endl << "请输入随机数范围的最大值:" ;
int number;
cin >> number;
srand( (unsigned) time(NULL) ); //用时间做种,每次产生随机数不一样
for ( int row = 0; row < pGraph->nVertexCount; ++row )
{
for ( int col = 0; col < pGraph->nVertexCount; ++col )
{
if (row == col)
pGraph->arrArcs[row][col] = 0;
else
pGraph->arrArcs[row][col] = rand() % ( number + 10 ); //产生0 - (number+10)的随机数

// 如果输入数据大于number,那么视作距离为无穷远,用MAX_DISTANCE代表
if (pGraph->arrArcs[row][col] >= number )
pGraph->arrArcs[row][col] = MAX_DISTANCE;
}
}
}
else
{
cout << endl << "请输入邻接矩阵数据(非负数,按行输入,大于9999的数代表无穷远):" << endl;
for ( int row = 0; row < pGraph->nVertexCount; ++row )
{
for ( int col = 0; col < pGraph->nVertexCount; ++col )
{
cin >> pGraph->arrArcs[row][col];

// 如果输入数据大于9999,那么距离为无穷远,用MAX_DISTANCE代表
if (pGraph->arrArcs[row][col] > 9999)
pGraph->arrArcs[row][col] = MAX_DISTANCE;
}
}
}
cout << endl << "/////////////////////////////邻接矩阵/////////////////////////////////////" << endl;
for ( int row = 0; row < pGraph->nVertexCount; ++row )
{
for ( int col = 0; col < pGraph->nVertexCount; ++col )
{
if ( pGraph->arrArcs[row][col] == MAX_DISTANCE)
cout << "   OC ";
else
printf("%5d ",  pGraph->arrArcs[row][col]);
}
cout << endl;
}
cout << endl;
cout << "//////////////////////////////////////////////////////////////////////////" << endl << endl;
}


3.3 Dijkstra算法

/************************************************************************/
/* Dijkstra算法:求出从i到任意节点的最短路径
*/
/*
参数:
int arrArcs[][MAX_VERTEX_COUNT],          有向图邻接矩阵
const int nVertexCount,                   节点数目
const int startVertex,                    源节点
int *pDistance,                            各个节点到达源节点的距离
int *pPreVertex                           各个节点的前一个节点
*/
/************************************************************************/

void Dijkstra(int arrArcs[][MAX_VERTEX_COUNT], const int nVertexCount,  const int startVertex, int *pDistance, int *pPreVertex)
{
// isIns用于判断所有的节点是否在S集合中,初始为false,每进入一个设置对应为true,直到所有为true,算法停止
vector<bool> isInS;                  //是否已经在S集合中(S中的点均已算出从i到其的最短路径)
isInS.reserve(0);                    // 设置大小为0
isInS.assign(nVertexCount, false);   //重新分配vector大小,所有的节点都不在S集合中

int i, j;
// Step 1: 先求出i,j之间不通过第三方节点转发的距离
//         初始化pDistance和pPreVertex数组,此时可以求出i->j不通过其他点的距离
for(j =0; j < nVertexCount; ++j)
{
// 第一次遍历时,查找的最短距离为两点之间不通过第三方的最短距离
pDistance[j] = arrArcs[startVertex][j];
if(arrArcs[startVertex][j] < MAX_DISTANCE)
pPreVertex[j] = startVertex;  // i,j之间可以直连,那么j的前序节点便是i
else
pPreVertex[j] = -1;       // -1表示前一节点未知
}
pPreVertex[startVertex] = -1;     // 开始节点的前序节点未知

// Step 2: 求出i,j之间通过第三方节点k转发的最短距离
/*开始使用贪心思想循环处理不在S集合中的每一个节点*/
isInS[startVertex] = true;          //开始节点放入S集合中
int k = startVertex;                // 标记中间节点

//开始节点已经存放在S中了,还有nVertexCount-1个节点要处理,故i从1开始
for (i = 1; i < nVertexCount; i ++)
{

// Step 2.1 : 寻找不在S集合中的距离i的distance最小的节点(依次遍历距离矩阵)
int nextVertex = k;
int tempDistance = MAX_DISTANCE;
for(j = 0; j < nVertexCount; ++j)
{
//寻找不在S集合中的距离i的distance最小的节点
if((isInS[j] == false) && (pDistance[j] < tempDistance))
{
nextVertex = j;
tempDistance = pDistance[j];
}
}
// 标记:一轮循环后,可以求得在当前S下,距离i的最近的不在S中的点,并保存数据
isInS[nextVertex] = true; //距离i最近的节点nextVertex放入S集合中
k = nextVertex;           //下一次寻找的开始节点k

// Step 2.2 : 在S加入新节点后,计算从i到j的最短距离,更新distance:
//            以k为新考虑的中间点,计算从i通过k转发到达j的距离,并与原有的从i直接到j的距离进行比较,选取最小值
for (j =0; j < nVertexCount; j ++)
{
// 仅需计算不在S中的节点(从i出发到达S中的节点的距离是最短的)
if (isInS[j] == false && arrArcs[k][j] < MAX_DISTANCE)
{
if (pDistance[ k ] + arrArcs[ k ][ j ] < pDistance[ j ]) //以k为新考虑的中间点,计算从i通过k转发到达j的距离
{
pDistance[ j ] = pDistance[ k ] + arrArcs[ k ][ j ];
pPreVertex[ j ] = k;
}
}
}
}
}


3.4 Floyd 算法

/************************************************************************/
/* Floyd 算法:求出所有节点两两之间的最短路径
*/
/*
参数:
Graph * pGraph,                       图的数据结构
int arrDistance[][MAX_VERTEX_COUNT],  最短距离
int arrPath[][MAX_VERTEX_COUNT],      最短路径索引
int nVertexCount                      节点数目
*/
/************************************************************************/
void Floyd(Graph * pGraph, int arrDistance[][MAX_VERTEX_COUNT], int arrPath[][MAX_VERTEX_COUNT])
{
int i, j, k;
int nVertexCount = pGraph->nVertexCount;
// Step 1:初始化arrDistance矩阵和arrPath矩阵
//     第一次循环时,设置i,j之间的距离即为两者之间直线距离;
//     从i出发的到达j的任一节点的前序节点都是i
for ( i = 0; i < nVertexCount; ++i )
{
for ( j = 0; j < nVertexCount; ++j )
{
arrDistance[i][j] = pGraph->arrArcs[i][j];
arrPath[i][j] = i;
}
}
// Step 2:动态规划
// Dis(i,j)为节点i到节点j的最短路径的距离,
//      对于每一个节点k,检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,
//      如果成立,证明从i到k再到j的路径比i直接到j的路径短,便设置Dis(i,j) = Dis(i,k) + Dis(k,j)
//      当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离

for ( k = 0; k < nVertexCount; ++k )
{
for ( i = 0; i < nVertexCount; ++i )
{
for ( j = 0; j < nVertexCount; ++j )
{
// 对于每一个节点k,检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,
if ( arrDistance[i][k] + arrDistance[k][j] < arrDistance[i][j] )
{
// 找到更短路径
arrDistance[i][j] = arrDistance[i][k] + arrDistance[k][j];
// 存储路径索引值
arrPath[i][j] = arrPath[k][j];
}
}
}
}
}


3.5 最短路径输出模块

为了方便输出实验结果,设计了两个输出函数:

1) Dijkstra算法输出函数

/************************************************************************/
/* Dijkstra 算法结果输出函数:输出Floyd算法的最短路径
*/
/*
参数:
int *pDistance,                           各个节点到达源节点的距离
int *pPreVertex                           各个节点的前一个节点
int nVertexCount,                         顶点数目
int startVertex,                          源节点
*/
/************************************************************************/
void DijkstraPrintResult(int *pDistance, int *pPreVertex, int nVertexCount, int startVertex)
{
int i, j;
i = startVertex;
for(j =0; j < nVertexCount; ++j)
{
if (j!=i) // 节点不为自身
{
printf("%2d -> %2d \t\t", i, j);
if ( pDistance[j] == MAX_DISTANCE)
cout << "OC\t\t";
else
cout << pDistance[j] << "\t\t";

int index = j;
stack<int > trace;
// 逆向查找最短路径,并放置到stack
while (pPreVertex[index] != -1) {
trace.push(pPreVertex[index]);
index = pPreVertex[index];
}

// 退栈,即可得到正确的路径
if (!trace.empty()) //非空
{
while (!trace.empty()) {
cout << trace.top() << " -> ";
trace.pop();
}
}
else
{
cout  << i << " -> ";
}
cout << j << endl;
}
}
}


2)Floyd算法输出函数

/************************************************************************/
/* Floyd 算法结果输出函数:输出Floyd算法的最短路径
*/
/*
参数:
int arrDistance[][MAX_VERTEX_COUNT],     最短路径距离
int arrPath[][MAX_VERTEX_COUNT],         最短路径节点索引
int nVertexCount                         顶点数目
*/
/************************************************************************/
void FloydPrintResult( int arrDistance[][MAX_VERTEX_COUNT], int arrPath[][MAX_VERTEX_COUNT], int nVertexCount )
{
cout << "源点 -> 目的点\t\t距离 \t\t 路径" << endl;

for ( int i = 0; i < nVertexCount; ++i )
{
for ( int j = 0; j < nVertexCount; ++j )
{
if ( i != j )   // 节点不是自身
{
printf("%2d -> %2d \t\t", i, j);
if ( arrDistance[i][j] == MAX_DISTANCE)
cout << "OC\t\t";
else
cout << arrDistance[i][j] << "\t\t";

int index = j;
stack<int > trace;
// 逆向查找最短路径,并放置到stack
do
{
index = arrPath[i][index];
trace.push( index );
} while ( index != i );

// 退栈,即可得到正确的路径
while (!trace.empty()) {
cout << trace.top() << " -> ";
trace.pop();
}
cout << j << endl;
}
}
}
}


4.完整的实现代码

#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>

using std::cout;
using std::endl;
using std::cin;
using std::vector;
using std::stack;

#define MAX_DISTANCE 9999 // 最大值
#define MAX_VERTEX_COUNT 50// 最大顶点个数
//////////////////////////////////////////////////////////////////////////

typedef struct _Graph { int arrArcs[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT]; // 邻接矩阵 int nVertexCount; // 顶点数量 int nArcCount; // 边的数量 } Graph;
//////////////////////////////////////////////////////////////////////////

/************************************************************************/ /* 图数据录入算法:根据命令行提示将邻接矩阵存储到图Graph中 录入方式有两种,自动生成和手动录入 */ /* 参数: Graph *pGraph 图数据结构 */ /************************************************************************/ void StoreGraphData( Graph *pGraph ) { cout << "算法采用邻接矩阵来存储图的相关数据,因此请按指示输入数据" << endl; cout << "请输入顶点数量(最多50个顶点): "; cin >> pGraph->nVertexCount; cout << "请输入边的数量: "; cin >> pGraph->nArcCount; cout << endl << "自动生成邻接矩阵请输入1,手动输入邻接矩阵请输入0:" ; int nWay = 1; cin >> nWay; if ( 1 == nWay) // 自动生成 { cout << endl << "请输入随机数范围的最大值:" ; int number; cin >> number; srand( (unsigned) time(NULL) ); //用时间做种,每次产生随机数不一样 for ( int row = 0; row < pGraph->nVertexCount; ++row ) { for ( int col = 0; col < pGraph->nVertexCount; ++col ) { if (row == col) pGraph->arrArcs[row][col] = 0; else pGraph->arrArcs[row][col] = rand() % ( number + 10 ); //产生0 - (number+10)的随机数 // 如果输入数据大于number,那么视作距离为无穷远,用MAX_DISTANCE代表 if (pGraph->arrArcs[row][col] >= number ) pGraph->arrArcs[row][col] = MAX_DISTANCE; } } } else { cout << endl << "请输入邻接矩阵数据(非负数,按行输入,大于9999的数代表无穷远):" << endl; for ( int row = 0; row < pGraph->nVertexCount; ++row ) { for ( int col = 0; col < pGraph->nVertexCount; ++col ) { cin >> pGraph->arrArcs[row][col]; // 如果输入数据大于9999,那么距离为无穷远,用MAX_DISTANCE代表 if (pGraph->arrArcs[row][col] > 9999) pGraph->arrArcs[row][col] = MAX_DISTANCE; } } } cout << endl << "/////////////////////////////邻接矩阵/////////////////////////////////////" << endl; for ( int row = 0; row < pGraph->nVertexCount; ++row ) { for ( int col = 0; col < pGraph->nVertexCount; ++col ) { if ( pGraph->arrArcs[row][col] == MAX_DISTANCE) cout << " OC "; else printf("%5d ", pGraph->arrArcs[row][col]); } cout << endl; } cout << endl; cout << "//////////////////////////////////////////////////////////////////////////" << endl << endl; }

/************************************************************************/ /* Dijkstra算法:求出从i到任意节点的最短路径 */ /* 参数: int arrArcs[][MAX_VERTEX_COUNT], 有向图邻接矩阵 const int nVertexCount, 节点数目 const int startVertex, 源节点 int *pDistance, 各个节点到达源节点的距离 int *pPreVertex 各个节点的前一个节点 */ /************************************************************************/ void Dijkstra(int arrArcs[][MAX_VERTEX_COUNT], const int nVertexCount, const int startVertex, int *pDistance, int *pPreVertex) { // isIns用于判断所有的节点是否在S集合中,初始为false,每进入一个设置对应为true,直到所有为true,算法停止 vector<bool> isInS; //是否已经在S集合中(S中的点均已算出从i到其的最短路径) isInS.reserve(0); // 设置大小为0 isInS.assign(nVertexCount, false); //重新分配vector大小,所有的节点都不在S集合中 int i, j; // Step 1: 先求出i,j之间不通过第三方节点转发的距离 // 初始化pDistance和pPreVertex数组,此时可以求出i->j不通过其他点的距离 for(j =0; j < nVertexCount; ++j) { // 第一次遍历时,查找的最短距离为两点之间不通过第三方的最短距离 pDistance[j] = arrArcs[startVertex][j]; if(arrArcs[startVertex][j] < MAX_DISTANCE) pPreVertex[j] = startVertex; // i,j之间可以直连,那么j的前序节点便是i else pPreVertex[j] = -1; // -1表示前一节点未知 } pPreVertex[startVertex] = -1; // 开始节点的前序节点未知 // Step 2: 求出i,j之间通过第三方节点k转发的最短距离 /*开始使用贪心思想循环处理不在S集合中的每一个节点*/ isInS[startVertex] = true; //开始节点放入S集合中 int k = startVertex; // 标记中间节点 //开始节点已经存放在S中了,还有nVertexCount-1个节点要处理,故i从1开始 for (i = 1; i < nVertexCount; i ++) { // Step 2.1 : 寻找不在S集合中的距离i的distance最小的节点(依次遍历距离矩阵) int nextVertex = k; int tempDistance = MAX_DISTANCE; for(j = 0; j < nVertexCount; ++j) { //寻找不在S集合中的距离i的distance最小的节点 if((isInS[j] == false) && (pDistance[j] < tempDistance)) { nextVertex = j; tempDistance = pDistance[j]; } } // 标记:一轮循环后,可以求得在当前S下,距离i的最近的不在S中的点,并保存数据 isInS[nextVertex] = true; //距离i最近的节点nextVertex放入S集合中 k = nextVertex; //下一次寻找的开始节点k // Step 2.2 : 在S加入新节点后,计算从i到j的最短距离,更新distance: // 以k为新考虑的中间点,计算从i通过k转发到达j的距离,并与原有的从i直接到j的距离进行比较,选取最小值 for (j =0; j < nVertexCount; j ++) { // 仅需计算不在S中的节点(从i出发到达S中的节点的距离是最短的) if (isInS[j] == false && arrArcs[k][j] < MAX_DISTANCE) { if (pDistance[ k ] + arrArcs[ k ][ j ] < pDistance[ j ]) //以k为新考虑的中间点,计算从i通过k转发到达j的距离 { pDistance[ j ] = pDistance[ k ] + arrArcs[ k ][ j ]; pPreVertex[ j ] = k; } } } } }

/************************************************************************/ /* Floyd 算法:求出所有节点两两之间的最短路径 */ /* 参数: Graph * pGraph, 图的数据结构 int arrDistance[][MAX_VERTEX_COUNT], 最短距离 int arrPath[][MAX_VERTEX_COUNT], 最短路径索引 int nVertexCount 节点数目 */ /************************************************************************/ void Floyd(Graph * pGraph, int arrDistance[][MAX_VERTEX_COUNT], int arrPath[][MAX_VERTEX_COUNT]) { int i, j, k; int nVertexCount = pGraph->nVertexCount; // Step 1:初始化arrDistance矩阵和arrPath矩阵 // 第一次循环时,设置i,j之间的距离即为两者之间直线距离; // 从i出发的到达j的任一节点的前序节点都是i for ( i = 0; i < nVertexCount; ++i ) { for ( j = 0; j < nVertexCount; ++j ) { arrDistance[i][j] = pGraph->arrArcs[i][j]; arrPath[i][j] = i; } } // Step 2:动态规划 // Dis(i,j)为节点i到节点j的最短路径的距离, // 对于每一个节点k,检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立, // 如果成立,证明从i到k再到j的路径比i直接到j的路径短,便设置Dis(i,j) = Dis(i,k) + Dis(k,j) // 当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离 for ( k = 0; k < nVertexCount; ++k ) { for ( i = 0; i < nVertexCount; ++i ) { for ( j = 0; j < nVertexCount; ++j ) { // 对于每一个节点k,检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立, if ( arrDistance[i][k] + arrDistance[k][j] < arrDistance[i][j] ) { // 找到更短路径 arrDistance[i][j] = arrDistance[i][k] + arrDistance[k][j]; // 存储路径索引值 arrPath[i][j] = arrPath[k][j]; } } } } }

/************************************************************************/ /* Dijkstra 算法结果输出函数:输出Floyd算法的最短路径 */ /* 参数: int *pDistance, 各个节点到达源节点的距离 int *pPreVertex 各个节点的前一个节点 int nVertexCount, 顶点数目 int startVertex, 源节点 */ /************************************************************************/ void DijkstraPrintResult(int *pDistance, int *pPreVertex, int nVertexCount, int startVertex) { int i, j; i = startVertex; for(j =0; j < nVertexCount; ++j) { if (j!=i) // 节点不为自身 { printf("%2d -> %2d \t\t", i, j); if ( pDistance[j] == MAX_DISTANCE) cout << "OC\t\t"; else cout << pDistance[j] << "\t\t"; int index = j; stack<int > trace; // 逆向查找最短路径,并放置到stack while (pPreVertex[index] != -1) { trace.push(pPreVertex[index]); index = pPreVertex[index]; } // 退栈,即可得到正确的路径 if (!trace.empty()) //非空 { while (!trace.empty()) { cout << trace.top() << " -> "; trace.pop(); } } else { cout << i << " -> "; } cout << j << endl; } } }

/************************************************************************/ /* Floyd 算法结果输出函数:输出Floyd算法的最短路径 */ /* 参数: int arrDistance[][MAX_VERTEX_COUNT], 最短路径距离 int arrPath[][MAX_VERTEX_COUNT], 最短路径节点索引 int nVertexCount 顶点数目 */ /************************************************************************/ void FloydPrintResult( int arrDistance[][MAX_VERTEX_COUNT], int arrPath[][MAX_VERTEX_COUNT], int nVertexCount ) { cout << "源点 -> 目的点\t\t距离 \t\t 路径" << endl; for ( int i = 0; i < nVertexCount; ++i ) { for ( int j = 0; j < nVertexCount; ++j ) { if ( i != j ) // 节点不是自身 { printf("%2d -> %2d \t\t", i, j); if ( arrDistance[i][j] == MAX_DISTANCE) cout << "OC\t\t"; else cout << arrDistance[i][j] << "\t\t"; int index = j; stack<int > trace; // 逆向查找最短路径,并放置到stack do { index = arrPath[i][index]; trace.push( index ); } while ( index != i ); // 退栈,即可得到正确的路径 while (!trace.empty()) { cout << trace.top() << " -> "; trace.pop(); } cout << j << endl; } } } }

int main()
{
Graph graph;
// 存储数据到Graph结构
StoreGraphData( &graph );

/////////////////////////////Dijkstra/////////////////////////////////////
cout << "/////////////////////////////Dijkstra/////////////////////////////////////" << endl;
int * pDistance = new int [graph.nVertexCount]; // 存储从i到j的最短距离
int * pPreVertex = new int [graph.nVertexCount]; // 存储从i到j的最短路径

cout << "源点 -> 目的点\t\t距离 \t\t 路径" << endl;

for (int i =0 ; i < graph.nVertexCount; ++i )
{
Dijkstra(graph.arrArcs, graph.nVertexCount, i, pDistance, pPreVertex);
DijkstraPrintResult(pDistance, pPreVertex, graph.nVertexCount, i);
}

delete [] pDistance;
delete [] pPreVertex;
cout << "//////////////////////////////////////////////////////////////////////////" << endl << endl;
//////////////////////////////////////////////////////////////////////////

/////////////////////////////Floyd////////////////////////////////////////
cout << "/////////////////////////////Floyd////////////////////////////////////////" << endl;

int nArrDis[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT];
int nArrPath[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT];

Floyd(&graph, nArrDis, nArrPath);

FloydPrintResult( nArrDis, nArrPath, graph.nVertexCount );
cout << "//////////////////////////////////////////////////////////////////////////" << endl;
//////////////////////////////////////////////////////////////////////////

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: