#include<stdio.h>
#include<conio.h>
#define OK 1
#define ERROR -1
#define MAX_VERTEX_NUM 12
#define NETWORK_INFINITY 32767
typedef struct ArcCell {
int adj;
//char *info;
}AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
int vexnum,arcnum;
int vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
}AMGraph;
int LocateVex( AMGraph G,int name ) //返回顶点标号为name的顶点,在数组vexs[]中的位置
{
int ivex;
for(ivex = 0;ivex < G.vexnum ;ivex ++)
if(name == G.vexs[ivex])
return ivex;
return ERROR;
}
int CreateDN( AMGraph *G ) //创建有向网
{
int i,j,k;
int v1,v2,w;
printf("/n/n 图的顶点数<N>:"); scanf("%d",&(G->vexnum));
printf(" 图的弧数<E>:"); scanf("%d",&(G->arcnum));
printf("/n");
/*顶点编号或者名称*/
for(i = 0;i < G -> vexnum ;i ++){ printf(" 图的第%d个顶点的标号:",i+1); scanf("%d",(G->vexs)+i); }
/*初始化邻接矩阵*/
for(i=0;i< G->vexnum ;i++)
for(j=0;j< G->vexnum ;j++){
(G->arcs)[i][j].adj = NETWORK_INFINITY;
if(i == j) (G->arcs)[i][i].adj = 0;
}
/* 构造邻接矩阵 */
for(k = 0;k < G -> arcnum;k ++)
{
printf("/n 第%d弧=>/n",k+1);
printf(" 弧 尾:");do{ scanf("%d",&v1);if((v1<0)||(v1>G->vexnum))printf(" ERROR/n The tail vertex:"); }while((v1<0)||(v1>G->vexnum));
printf(" 弧 头:");do{ scanf("%d",&v2);if((v2<0)||(v2>G->vexnum))printf(" ERROR/n The head vertex:"); }while((v2<0)||(v2>G->vexnum));
printf(" 权 重:");scanf("%d",&w);
i = LocateVex(*G,v1); j = LocateVex(*G,v2);
(G->arcs)[i][j].adj = w;
printf("/n");
}
return OK;
}
void ShortestPath_FLOYD(AMGraph *G,int p[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM], int d[MAX_VERTEX_NUM][MAX_VERTEX_NUM])
{
//用Floyd算法求有向图G中各对顶点v和w之间的最短距离p[v][w]及其
//带权长度 D[v][w] 。
//若 p[v][w][u] 为 TRUE ,则 u 是从 v 到 u 当前求得的最短路径上的顶点。
int v,w,u;
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] < NETWORK_INFINITY){ //从 v 到 w 有直接路径
p[v][w][v] = true;
p[v][w][w] = true;
}//if
}//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]) { //从 v 经 u 到 w 的一条更短路径
d[v][w] = d[v][u] + d[u][w];
for(int i = 0; i < G->vexnum; i ++) //记录路径
p[v][w][i] = (p[v][u][i]||p[u][w][i]);
}
}
/*============================主函数main()====================================*/
int main( void )
{
int i,j;
int vexname;
AMGraph G;
//Dijkstra
int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int DistancMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
CreateDN( &G );
printf("创建的图的邻接矩阵:/n");
for(i = 0;i < G.vexnum;i ++){
for(j = 0;j < G.vexnum;j ++)
printf("%6d",G.arcs[i][j].adj);
printf("/n");
}
printf("/n/n各个顶点之间的最短距离矩阵:/n");
ShortestPath_FLOYD(&G, PathMatrix, DistancMatrix);
for(i = 0;i < G.vexnum;i ++){
for(j = 0;j < G.vexnum;j ++)
printf("%6d",DistancMatrix[i][j]);
printf("/n");
}
printf("/n/n");
for(i = 0;i < G.vexnum;i ++) {
for(j = 0;j < G.vexnum;j ++) { //输出最短路径矩阵
printf("<v%d,v%d>=> 距离=%-4d 路径=",G.vexs[i],G.vexs[j],DistancMatrix[i][j]);
printf("<v%d,",G.vexs[i]);
for(int u = 0; u < G.vexnum; u ++)
if(PathMatrix[i][j][u] && i!=u && j!=u)
printf("v%d,",G.vexs[u]);
printf("v%d>",G.vexs[j]);
printf("/n");
}
printf("/n");
}
getch();
return 0;
}