//最短路径-一个顶点到各点
#include<stdio.h>
#define MAX 30
#define TRUE 1
#define FALSE 0
#define INFINITY 1000
typedef enum{DG,DN,UDG,UDN} Graphkind;
typedef struct arccell //定义表示弧的邻接矩阵
{
int adj;
int *info; //弧的相关信息
}arccell,adjmatrix[MAX][MAX];
typedef struct //定义一个图类型
{
int vexs[MAX];
adjmatrix arcs;
int vexnum,arcnum;
Graphkind kind;
}mgraph;
typedef int pathmatrix[MAX][MAX][MAX];
typedef int distancmatrix[MAX][MAX];
///
//找出值为v的顶点在图的存储数组中的索引
int locatevex(mgraph g,int v)
{
for(int i=0;i<g.vexnum;++i)
if(g.vexs[i]==v)return i;
}
int createDN(mgraph &G) //构造有向网
{
int i,j,k;
int v1,v2,w;
printf("输入有向网的顶点个数和边的个数:/n");
scanf("%d%d",&G.vexnum,&G.arcnum);
printf("输入有向网的各顶点的值:/n");
for(i=0;i<G.vexnum;++i)
scanf("%d",&G.vexs[i]);
for(i=0;i<G.vexnum;++i)
for(j=0;j<G.vexnum;++j)
{
G.arcs[i][j].adj=INFINITY;
G.arcs[i][j].info=0;
if(i==j)G.arcs[i][j].adj=0;
}
for(k=0;k<G.arcnum;++k)
{
printf("输入无向网边的两个关联顶点和边的权值:/n");
scanf("%d%d%d",&v1,&v2,&w);
i=locatevex(G,v1);
j=locatevex(G,v2);
G.arcs[i][j].adj=w;
}
return 1;
}
//求任意两个顶点间的最短路径,用P返回路径,用D返回路径的权值
//若P[v][w][u]为TRUE则表明u为v到w的当前最短路径中的点
void shortpath_FLOYD(mgraph G,pathmatrix &P,distancmatrix &D)
{
int v,w,u,i;
for(v=0;v<G.vexnum;++v)
for(w=0;w<G.vexnum;++w)
{
D[v][w]=G.arcs[v][w].adj;//初始化表示各边权值的矩阵
for(u=0;u<G.vexnum;++u)P[v][w][u]=FALSE; //初始化表示路径的矩阵
if(D[v][w]<INFINITY) //从v到w有直接路径
{P[v][w][v]=TRUE;P[v][w][w]=TRUE;} //将v和w在路径矩阵中标示出来
}//for
//开始查找最短路径
for(u=0;u<G.vexnum;++u)
for(v=0;v<G.vexnum;++v)
for(w=0;w<G.vexnum;++w)
if(D[v][u]+D[u][w]<D[v][w])
{
D[v][w]=D[v][u]+D[u][w];
for(i=0;i<G.vexnum;++i)
P[v][w][i]=P[v][u][i] || P[u][w][i];
}//if
}//shortpath_FLOYD
//将两个顶点的最短路径显示出来的函数
void print_FLOYD(mgraph G,pathmatrix P,distancmatrix D)
{
int i,a,b,m,n;
printf("依次输入您要查询的两个顶点:/n");
scanf("%d%d",&a,&b);
m=locatevex(G,a);
n=locatevex(G,b);
if(D[m][n]==1000)printf("从%d到%d无路径/n",a,b);
else
{
printf("从%d到%d的长度为:%d/n经过的顶点有:/n",a,b,D[m][n]);
for(i=0;i<G.vexnum;++i)
if(P[m][n][i]==TRUE)printf("%d ",G.vexs[i]);
}
printf("/n");
}
void main()
{
pathmatrix p;
distancmatrix d;
mgraph g;
createDN(g);
shortpath_FLOYD(g,p,d);
while(1)
{
print_FLOYD(g,p,d);
}
}