//主要源代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INF 999999
#define MAX_NAME 3
#define VERTEX_MAX_NUM 100
typedef char VertexType[MAX_NAME];
typedef int VRType;
typedef struct { //建立邻接矩阵
int weight;
}adjMatrix[VERTEX_MAX_NUM][VERTEX_MAX_NUM];
struct MGraph{
VertexType vex[VERTEX_MAX_NUM];//建立顶点向量
adjMatrix arcs; //图中的邻接矩阵
int vrtnum,arcnum;//顶点,弧的个数
};
int LocateVex(MGraph G,VertexType u){
int i;
for( i=0;i<G.vrtnum;i++)
if(strcmp(u,G.vex[i])==0)
return i;
return -1;
}
void creatMGraph(MGraph &G){
int i,j,w;
VertexType va,vb;
printf("请输入无向图G的顶点数、边数:");
scanf("%d %d",&G.vrtnum,&G.arcnum);
printf("请输入%d个顶点的值:\n",G.vrtnum);
for(i=0;i<G.vrtnum;i++) //构造顶点向量,(其实就是将顶点的名字换成数字)
scanf("%s",G.vex[i]);
for(i=0;i<G.vrtnum;i++) //初始化邻接矩阵,都赋为无穷
for(j=0;j<G.vrtnum;j++)
G.arcs[i][j].weight=INF;
printf("请输入%d条边的顶点1 顶点2 权值(以空格为间隔):\n",G.vrtnum);
for(int k=0;k<G.arcnum;k++){
scanf("%s%s%d%*c",va,vb,&w);
i=LocateVex(G,va);
j=LocateVex(G,vb);
G.arcs[i][j].weight=w;
}
}
void DisplayArc(MGraph g){
printf("建立的邻接矩阵如下:\n ");
for(int i=0;i<g.vrtnum;i++)
printf("%7s",g.vex[i]);
printf("\n");
for(int i=0;i<g.vrtnum;i++){
printf("%s",g.vex[i]);
for(int j=0;j<g.vrtnum;j++){
if(g.arcs[i][j].weight==INF)
printf(" ∞");
else
printf("%7d",g.arcs[i][j].weight);
}
printf("\n");
}
}
void Dijkstra(MGraph G,VertexType v0){
int P[G.vrtnum][G.vrtnum];//pathMatrix路径矩阵
int D[G.vrtnum];//shortPathValue最短路径值
int final[G.vrtnum];//值为1代表已求得v0到v的最短路径,0则没有
int v,w,i,j,min;
int startVRT=LocateVex(G,v0);
for(v=0;v<G.vrtnum;v++){
final[v]=0;
D[v]=G.arcs[startVRT][v].weight;//初值为各个点到v0的距离
for(w=0;w<G.vrtnum;w++)
P[v][w]=0;//初始化,任何两个点之间没有直接路径
if(D[v]<INF)//如果到v0点有直接路径
P[v][startVRT]=P[v][v]=1;//p[v][]表示v0到v最短六级经过的点
}
D[startVRT]=0;//v0到自己的距离为0
final[startVRT]=1;
for(i=1;i<G.vrtnum;i++){
min=INF;
for(w=0;w<G.vrtnum;w++){
if(!final[w]&&D[w]<min){
v=w;
min=D[w];
}
}
final[v]=1;//v点并入已查找的点
for(w=0;w<G.vrtnum;w++){
if(!final[w]&&min<INF&&G.arcs[v][w].weight<INF&&(min+G.arcs[v][w].weight<D[w])){
D[w]=min+G.arcs[v][w].weight;
for(j=0;j<G.vrtnum;j++)
P[w][j]=P[v][j];
P[w][w]=1;
}
}
}
printf("最短路径数组如下:\n");
for(i=0;i<G.vrtnum;i++){
for(j=0;j<G.vrtnum;j++)
printf("%2d ",P[i][j]);
printf("\n");
}
printf("%s到各点的最短路径长度为:\n",G.vex[startVRT]);
for(i=0;i<G.vrtnum;i++)
if(i!=0)
printf("(%s-%s) %d\n",G.vex[startVRT],G.vex[i],D[i]);
}
int main(){
MGraph g;
creatMGraph(g);
DisplayArc(g);
Dijkstra(g,g.vex[0]);
return 0;
}
/*
测试样例
v0 v1 v2 v3 v4
v0 v1 10
v0 v4 100
v1 v2 50
v2 v4 10
v3 v2 20
v3 v4 60
v0 v3 30
*/