#include<stdio.h>
#include<stdlib.h>
typedef int Edgetype;//存储边的关系
typedef char VerType;//定点类型应由用户定义
#define MAXVER 100
#define INFINITY 66235
typedef struct {
VerType ver[MAXVER];
Edgetype edeget[MAXVER][MAXVER];
int numVertexes,numEdges;//输入当前的节点数,与边书
}MGraph;
MGraph creatGraph();
void MiniSpaTree(MGraph G);
int find(int parent[],int f);
//void Dijkstra(int p[],int d[],int v0,MGraph G);
void Floyd_dis(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER], MGraph G);
void show(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER], MGraph G,int v0,int v1);
int main(){
MGraph G = creatGraph();
int p[MAXVER][MAXVER],d[MAXVER][MAXVER],v0 = 0;
Floyd_dis(p,d,G);
//printf("%d",d[2]);
show(p,d,G,0,3);
return 0;
}
MGraph creatGraph()
{
int i,j,k,w;
MGraph G;
printf("请输入节点总数,与边的总数");
scanf("%d%d",&G.numVertexes,&G.numEdges);
getchar();
for(i=0;i<G.numVertexes;i++)
{
printf("请输入第%d个节点的数据",i+1);
scanf("%c",&G.ver[i]);
// printf("%c",G.ver[i]);
getchar();
}
//设置个边的关系
for(i=0;i<G.numEdges;i++)
{
for(j=0;j<G.numEdges;j++)
{
if(i==j)
G.edeget[i][j]=0;
else
G.edeget[i][j] = INFINITY;
}
}
//printf("dafg");
for(k=0;k<G.numEdges;k++)
{
printf("请输入vi,vj边上的序号:");
scanf("%d%d",&i,&j);
printf("请输入权值");
scanf("%d",&w);
G.edeget[i][j]= w;
G.edeget[j][i] = w;
}
return G;
}
/*
根据弗洛伊德算法求最短路径,、
思路: 相当于一五边形分割成了多个三角形
详情:http://blog.csdn.net/zhongkeli/article/details/8832946
定义了两个二维数组,p[][]用p来存储每次改变路径是的中间点(也就是所谓的前驱矩阵)
d[]是用来存储当前已经求得某些点的最短距离,所以要利用for语句将所有点都遍历一到
*/
//---------------------------------------------------------------------
/*
弗洛伊德算法虽然时间复杂度为n^3,但是它可以一次性将 搞出所有点到其他任意一点的最短距离
优雅而又简洁
*/
void Floyd_dis(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER], MGraph G)
{
for(int i=0;i<G.numVertexes;i++)//初始化p,d
{
for(int j=0;j<G.numVertexes;j++)
{
d[i][j] = G.edeget[i][j];
p[i][j] = j;
}
}
for(int i=0;i<G.numVertexes;i++)//作为传说中的中间点
{
for(int j=0;j<G.numVertexes;j++)
{
for(int k=0;k<G.numVertexes;k++)
{
if(d[j][k] > (d[j][i]+d[i][k]))//有点像向量的加减
{
d[j][k] = d[j][i]+d[i][k];
//因为最后还是要遍历d[k][j]的所以无需管d[k][j]
p[j][k] = P[j][i]; //p[j][k]代表的是前驱
//因为j-k的路径不一定是直接存在的也可能用通过j的前驱找出来的
//所以p[j][k]不能存点的中间点的位置,而是应该存的是到中间的前驱
}
}
}
}
}
void show(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER], MGraph G,int v0,int v1)
{
char c= G.ver[v0];
//printf("%c ->",c);
int k = v0;
printf("The shortest distance = %d\n",d[v0][v1]);
//printf("%c ->",c);
while(k!=v1)
{
printf("%c ->",c);
k = p[k][v1];
// printf("%d",k);
c = G.ver[k];
}
printf("%c",c) ;
#include<stdlib.h>
typedef int Edgetype;//存储边的关系
typedef char VerType;//定点类型应由用户定义
#define MAXVER 100
#define INFINITY 66235
typedef struct {
VerType ver[MAXVER];
Edgetype edeget[MAXVER][MAXVER];
int numVertexes,numEdges;//输入当前的节点数,与边书
}MGraph;
MGraph creatGraph();
void MiniSpaTree(MGraph G);
int find(int parent[],int f);
//void Dijkstra(int p[],int d[],int v0,MGraph G);
void Floyd_dis(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER], MGraph G);
void show(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER], MGraph G,int v0,int v1);
int main(){
MGraph G = creatGraph();
int p[MAXVER][MAXVER],d[MAXVER][MAXVER],v0 = 0;
Floyd_dis(p,d,G);
//printf("%d",d[2]);
show(p,d,G,0,3);
return 0;
}
MGraph creatGraph()
{
int i,j,k,w;
MGraph G;
printf("请输入节点总数,与边的总数");
scanf("%d%d",&G.numVertexes,&G.numEdges);
getchar();
for(i=0;i<G.numVertexes;i++)
{
printf("请输入第%d个节点的数据",i+1);
scanf("%c",&G.ver[i]);
// printf("%c",G.ver[i]);
getchar();
}
//设置个边的关系
for(i=0;i<G.numEdges;i++)
{
for(j=0;j<G.numEdges;j++)
{
if(i==j)
G.edeget[i][j]=0;
else
G.edeget[i][j] = INFINITY;
}
}
//printf("dafg");
for(k=0;k<G.numEdges;k++)
{
printf("请输入vi,vj边上的序号:");
scanf("%d%d",&i,&j);
printf("请输入权值");
scanf("%d",&w);
G.edeget[i][j]= w;
G.edeget[j][i] = w;
}
return G;
}
/*
根据弗洛伊德算法求最短路径,、
思路: 相当于一五边形分割成了多个三角形
详情:http://blog.csdn.net/zhongkeli/article/details/8832946
定义了两个二维数组,p[][]用p来存储每次改变路径是的中间点(也就是所谓的前驱矩阵)
d[]是用来存储当前已经求得某些点的最短距离,所以要利用for语句将所有点都遍历一到
*/
//---------------------------------------------------------------------
/*
弗洛伊德算法虽然时间复杂度为n^3,但是它可以一次性将 搞出所有点到其他任意一点的最短距离
优雅而又简洁
*/
void Floyd_dis(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER], MGraph G)
{
for(int i=0;i<G.numVertexes;i++)//初始化p,d
{
for(int j=0;j<G.numVertexes;j++)
{
d[i][j] = G.edeget[i][j];
p[i][j] = j;
}
}
for(int i=0;i<G.numVertexes;i++)//作为传说中的中间点
{
for(int j=0;j<G.numVertexes;j++)
{
for(int k=0;k<G.numVertexes;k++)
{
if(d[j][k] > (d[j][i]+d[i][k]))//有点像向量的加减
{
d[j][k] = d[j][i]+d[i][k];
//因为最后还是要遍历d[k][j]的所以无需管d[k][j]
p[j][k] = P[j][i]; //p[j][k]代表的是前驱
//因为j-k的路径不一定是直接存在的也可能用通过j的前驱找出来的
//所以p[j][k]不能存点的中间点的位置,而是应该存的是到中间的前驱
}
}
}
}
}
void show(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER], MGraph G,int v0,int v1)
{
char c= G.ver[v0];
//printf("%c ->",c);
int k = v0;
printf("The shortest distance = %d\n",d[v0][v1]);
//printf("%c ->",c);
while(k!=v1)
{
printf("%c ->",c);
k = p[k][v1];
// printf("%d",k);
c = G.ver[k];
}
printf("%c",c) ;
}
测试数据:0 1 1 1 3 7 3 6 3 6 8 7 8 7 4 7 5 5 5 2 7 2 0 5 1 2 3 6 7 2 3 4 2 6 4 6 7 4 9 5 4 3 2 4 1