//用邻接矩阵来设计floyd算法
//注意dijkstra算法和floyd算法本质都是在找最短距离,只不过前者是单源的,后者是是多源的
//并且时间复杂度都是n的立方
//但是确切来讲:前者的时间复杂度为2n的立方,后者的时间复杂度为n的立方,当n的规模足够大的话,后者的所用的时间还是要少很多的,并且floyd算法比较容易理解,算法比较简单
#include<stdio.h>
#include<stdlib.h>
#define maxsize 100
#define INFINITY 65535//表示不可达,一般用于初始化
typedef struct
{
int numnode, numedge;
int vert[maxsize];
int arc[maxsize][maxsize];
}pragh;//邻接矩阵的数据结构
void init(pragh *G)//图的初始化
{
printf("请输入顶点数和边数\n");
scanf_s("%d%d", &G->numedge, &G->numedge);
printf("图的初始化工作完毕\n");
}
void create(pragh* G)
{
int w,i,j;
printf("请分别输入顶点\n");
for ( i = 0; i < G->numnode; i++)
{
scanf_s("%d", &G->vert[i]);
}
for ( i = 0; i < G->numnode; i++)
{
for ( j = 0; j < G->numnode; j++)
{
G->arc[i][j] = INFINITY;
}
}
for (int i = 0; i < G->numedge; i++)
{
printf("请输入(i,j)边的下标i和j和权值w\n");
scanf_s("%d%d%d", &i, &j, &w);
G->arc[i][j] = w;
G->arc[j][i] = G->arc[i][j];
}
printf("图的初始化工作完毕\n");
}
typedef int Patharc[maxsize][maxsize];//存储的是顶点v到w的最短路径的下标,两个顶点的值都不确定,所以要用一个二维数组来表示
//注意在dijkstra算法中已经确定了是某个顶点到图中的某个顶点的下标,所以用一维数组就能搞定
typedef int shortpathtable[maxsize][maxsize];//存储的是顶点v到顶点w的权值
void shortpathfloyd(pragh G,Patharc *P,shortpathtable *D)
{
//注意想要改变某个对象,就要传入该对象的指针,否则在本质上是没有进行修改的
//所以在形参中传入的是一个指针,而不是一个本体
int i, j;
for (i = 0; i < G.numnode; i++)
{
for (j = 0; j < G.numnode; j++)
{
*(D)[i][j] = G.arc[i][j];//刚开始时D[i][j]的值为G->arc[i][j]的值
*(P)[i][j] = j;//初始化,即顶点i到顶点j的最短路径为j
}
}
for (int k = 0; k < G.numnode; k++)
{//最外面的那层for循环的k表示的是加入了哪个顶点了
//当floyd算法将所有的顶点都加入完成之后,就已经达到实验的目的了
//即找到了任意一个顶点到图中另外一个顶点的最短距离了
//因为每加入一个顶点,那个存储所有顶点到所有顶点的代价都会发生改变、
//当加入到最后一个顶点之后就代表已经是最优的了
for (i = 0; i < G.numnode;i++)
{
for (j = 0; j < G.numnode; j++)
{
if (*(D)[i][j] > *(D)[i][k] + *(D)[k][j])
{
//如果D[i][j]这两个顶点的距离要比加入了k这个结点(从0开始)大
//那么就更新,相当于每加入一个顶点之后D数组的内的全部数据都要更新
*(D)[i][j] = *(D)[i][k] + *(D)[k][j];
*(P)[i][j] = k;//将可以到达i到j这两个顶点,的路径改为k
//因为我们已经找到了一个更好的路径可以到达图中的这两各顶点了
}
}
}
}//当退出最外层循环,就已经达到了实验的目的,找到了图中任意一个顶点
//到其他顶点的最短路径了
printf("Floyd算法已经实现\n");
}
int main(void)
{
pragh G;
Patharc P;
shortpathtable D;
init(&G);
create(&G);
shortpathfloyd(G, &P,&D);
system("pause");
return 0;
}