#include<iostream>
#include<string>
using namespace std;
/*邻接矩阵的类型定义*/
#define MAX 10000000
#define MAX_VERTEX_NUM 20
typedef struct
{
string vexs[MAX_VERTEX_NUM];//用一维数组存储顶点信息
int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//用二维数组充当矩阵,来存储顶点边的信息
int vexnum,edgenum;//顶点树和边数
}MGraph;
/*构造有向网的邻接矩阵*/
void CreateDN_AM(MGraph &G,int n,int e)
{
G.vexnum=n;
G.edgenum=e;
int i,j,k;
int weight;
for(i=0;i<n;i++)
cin>>G.vexs[i];//输入顶点信息
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(i==j)
G.edges[i][j]=0;//主对角线上的权值为0
else
G.edges[i][j]=MAX;//将矩阵初始化为MAX
}
for(k=0;k<e;k++)
{
cin>>i>>j>>weight;
G.edges[i][j]=weight;
}
}
/*弗洛伊德算法求最短路径*/
void ShortestPath_Floyd(MGraph &G)
{
int i,j,k;
int dist[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
string path[2*MAX_VERTEX_NUM][2*MAX_VERTEX_NUM];
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
{//初始化工作
dist[i][j]=G.edges[i][j];
if(dist[i][j]<MAX)
path[i][j]=G.vexs[i]+G.vexs[j];
else
path[i][j]="";
}
//三个for循环求最短路径
for(k=0;k<G.vexnum;k++)
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
if(dist[i][k]+dist[k][j]<dist[i][j])
{
dist[i][j]=dist[i][k]+dist[k][j];
path[i][j]=path[i][k]+path[k][j];
}
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
cout<<path[i][j]<<" "<<dist[i][j]<<" ";
cout<<endl;
}
}
void main()
{
freopen("in.txt","r",stdin);
MGraph G;
CreateDN_AM(G,4,6);
ShortestPath_Floyd(G);
}
弗洛伊德算法主要是采用了dist二维数组来存储各个顶点之间的最短路径,然后不断更新,它的典型标识是有三个连续的for循环:将每一个顶点插入到另外两个顶点之间,看是否能得到较小的路径,这是它的主要思想,即是所谓的“试探”或是“动态”,其实理解是容易理解的,就是不好表达。
记得今年暑假在学校ACM培训时,老师讲到了这两个还有前面求最小路径的两个算法,当时的我,真的是没听懂啊,根本就看不懂这四个算法,是什么意思,但我对这四个算法记忆是那么的深,他们在我心里都有个死结了,今天终于搞懂他们了,比较开心啊。但是我对他们的熟练程度,几乎没有,也就是说要用的话,还需要再熟练一些,对他们的理解更深一些,嘿嘿,我会努力的,不过现在快要考试了,我还得紧张的复习,真舍不得不学数据结构啊!