用途:求一个图中每一对顶点之间的最短路径。
算法描述:
floyd算法的基本思想是动态规划。
假设 dis[i][j] 表示节点i到节点j的最短距离,则有如下递推公式:
dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
即节点i到节点j的最短路径有可能直接到达,也有可能借助另一节点k到达。其中,对k进行遍历,使dis[i][k] + dis[k][j]最小。因此,利用三层for循环,分别对k,i,j进行枚举,便可得到图中每一对顶点之间的最短路径。
代码如下:
#include <iostream>
using namespace std;
#define MAXNUM 100
#define INT_MAX 10000
void Floyd(int num,int G[MAXNUM][MAXNUM],int path[MAXNUM][MAXNUM],int dis[MAXNUM][MAXNUM])
{
//Floyd算法求i,j之间的最短路径(动态规划求解)
//初始化
for(int i = 0; i < num; i++)
{
for(int j = 0; j < num; j++)
{
if(G[i][j] != INT_MAX) //i,j直接相连
{
path[i][j] = j;
dis[i][j] = G[i][j];
}
else
{
path[i][j] = -1;
dis[i][j] = INT_MAX;
}
}
}
for(int k = 0; k < num; k++)
{
for(int i = 0; i < num; i++)
{
for(int j = 0; j < num; j++)
{
if(dis[i][j] > dis[i][k] + dis[k][j])
{
dis[i][j] = dis[i][k] + dis[k][j];
path[i][j] = path[i][k];
}
}
}
}
}
void GetInput(int &num,int G[MAXNUM][MAXNUM])
{
//得到用户输入
cin>>num;
for(int i = 0; i < num; i++)
{
for(int j = 0; j < num; j++)
{
cin>>G[i][j];
if(i == j)
{
G[i][j] = 0;
}
if(G[i][j] == -1) //输入-1表示i,j不直接连通
{
G[i][j] = INT_MAX;
}
}
}
}
void Output(int num,int path[MAXNUM][MAXNUM],int dis[MAXNUM][MAXNUM])
{
//输出搜索结果
for(int i = 0; i < num; i++)
{
for(int j = 0; j < num; j++)
{
cout<<"The shortest dis of "<<i<<"->"<<j<< ": "<<dis[i][j]<<endl;
}
}
}
int main()
{
int G[MAXNUM][MAXNUM] = {0}; //图的邻接矩阵
int num = 0; //节点数量
int path[MAXNUM][MAXNUM] = {0}; //存放最短路径,从i到j的最短路径首先经过k
int dis[MAXNUM][MAXNUM] = {0}; //存放最短路径值
GetInput(num,G); //初始化邻接矩阵
Floyd(num,G,path,dis); //Floyd算法
Output(num,path,dis); //输出结果
return 0;
}