#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
/*---------------------------------有向图<邻接矩阵>存储表示--------------------------*/
#define INFINITY 255
#define MAX_VERTEX_NUM 50
typedef char VertexType;
typedef struct ArcCell
{
int distance;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct
{
VertexType CityName[MAX_VERTEX_NUM][20];
AdjMatrix arcs;
int vexnum,arcnum;
}MGraph;
/*--------------------------------------函数菜单操作------------------------------*/
void ReturnMenu()
{
printf("\n\t****************************************************************\n");
printf("\t* 返回(Y) 退出(E) * \n");
printf("\t****************************************************************\n\n\n");
}
/*---------------------------------有向图<邻接矩阵>函数操作--------------------------*/
Status LocateVex(MGraph G,VertexType u[20])
{ /* 初始条件: 图G存在,u和G中顶点有相同特征 */
/* 操作结果: 若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 */
int i;
for(i=0;i<G.vexnum;++i)
if(strcmp(u,G.CityName[i])==0)
return i;
return -1;
}
Status CreatDN(MGraph &G)
{
int i,j,k,w;
VertexType v1[20],v2[20];
printf("请输入总城市数:\t");
scanf("%d",&G.vexnum);
printf("请输入各城市间路径数:\t");
scanf("%d",&G.arcnum);
fflush(stdin);
printf("\n\n------------------------下面请输入各城市名称------------------------\n\n");
for(i = 0;i < G.vexnum;i++)
{
printf("第%d个城市名为:\t",i+1);
gets(G.CityName[i]);
}
for(i = 0;i < G.vexnum;i++)
for(j = 0;j < G.arcnum; j++)
{
G.arcs[i][j].distance = INFINITY;
}
printf("\n\n------------------------下面请输入各城市间的距离--------------------\n\n");
for(k = 0;k < G.arcnum;k++)
{
printf("\n请输入第%d条路径信息:\n",k+1);
printf("请输入A城市名:\t");
gets(v1);
printf("请输入B城市名:\t");
gets(v2);
printf("请输入A城市和B城市间的距离:\t");
scanf("%d",&w);
fflush(stdin);
printf("\n");
i = LocateVex(G, v1);
j = LocateVex(G, v2);
G.arcs[i][j].distance = w;
}
return OK;
}
void ShortestPath_DIJ(MGraph G,int v0,int P[MAX_VERTEX_NUM][MAX_VERTEX_NUM],int D[MAX_VERTEX_NUM])
{
// 用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]
// 及其带权长度D[v]。
// 若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点。
// final[v]为TRUE当且仅当v∈S,即已经求得从v0到v的最短路径。
int i=0,j, v,w,min;
bool final[MAX_VERTEX_NUM];
for (v=0; v<G.vexnum; ++v)
{
final[v] = FALSE;
D[v] = G.arcs[v0][v].distance;
for (w=0; w<G.vexnum; ++w)
P[v][w] = FALSE; // 设空路径
if (D[v] < INFINITY)
{
P[v][v0] = TRUE;
P[v][v] = TRUE;
}
}
D[v0] = 0;
final[v0] = TRUE; // 初始化,v0顶点属于S集
//--- 开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集 ---
for (i=1; i<G.vexnum; ++i)
{ // 其余G.vexnum-1个顶点
min = INFINITY; // 当前所知离v0顶点的最近距离
for (w=0; w<G.vexnum; ++w)
if (!final[w]) // w顶点在V-S中
if (D[w]<min)
{
v = w;
min = D[w];
} // w顶点离v0顶点更近
final[v] = TRUE; // 离v0顶点最近的v加入S集
for (w=0; w<G.vexnum; ++w) // 更新当前最短路径及距离
if (!final[w] && (min+G.arcs[v][w].distance<D[w]))
{ // 修改D[w]和P[w], w∈V-S
D[w] = min + G.arcs[v][w].distance;
for(j=0;j<G.vexnum;j++)
P[w][j] = P[v][j]; //第v行赋值于第w行
P[w][w] = TRUE; // P[w] = P[v]+[w]
}
}
}
void showCityName(MGraph G)
{
int i;
char *ch;
printf("\n\t****************************************************************\n");
printf("\t* 城市名称显示 *\n");
printf("\t****************************************************************\n");
for(i = 0;i<G.vexnum;i++)
{
ch = G.CityName[i];
printf("\t* \t\t %d.",i+1);
while(*ch != '\0')
{
printf("%c",*ch);
ch++;
//puts(G.CityName[j]);
}
printf(" *\n");
}
printf("\t****************************************************************\n");
}
void mainprocess()
{
MGraph G;
int P[MAX_VERTEX_NUM][MAX_VERTEX_NUM], D[MAX_VERTEX_NUM],flags = 0;
int StartPoint,EndPoint,j,check,length,startcheck;
char placeStart[20],placeEnd[20],*ch,p;
CreatDN(G);
/* //测试数据所用
for( i = 0;i < G.vexnum;i++)
{
for( j = 0; j < G.vexnum;j++)
if(255 == G.arcs[i][j].distance)
printf(" 0");
else
printf("%4d",G.arcs[i][j].distance);
printf("\n");
}*/
do
{
system("cls");
showCityName(G);
LOOP1:
fflush(stdin);
printf("请输入起点名称:\t");
gets(placeStart);
StartPoint = LocateVex(G,placeStart);
//printf("起点下标=%d",StartPoint);
if(-1 == StartPoint)
{
printf("\n\t\t警告:无此起点名称!!\n");
goto LOOP1;
}
ShortestPath_DIJ(G,StartPoint,P,D);
LOOP2:
fflush(stdin);
printf("\n请输入终点名称:\t");
gets(placeEnd);
EndPoint = LocateVex(G,placeEnd);
//printf("终点下标=%d",EndPoint);
if(-1 == EndPoint)
{
printf("\n\t\t警告:无此终点名称!!\n");
goto LOOP2;
}
flags = 0;
printf("\n");
printf("\n\n-----------------------------结果----------------------------\n\n");
startcheck = 0;
printf("最短路线为:\t");
for(j = StartPoint;j < G.vexnum;j++)
{
check = P[EndPoint][j];
ch = G.CityName[j];
if(1 == check)
{
if(0 == flags)
printf("开始-->");
flags++;
while(*ch != '\0')
{
printf("%c",*ch);
ch++;
//puts(G.CityName[j]);
}
printf("-->");
}
else if(0 != check)
break;
}
if(0 != flags )
{
for(j = 0;j < StartPoint;j++)
{
check = P[EndPoint][j];
ch = G.CityName[j];
if(1 == check)
{
flags++;
while(*ch != '\0')
{
printf("%c",*ch);
ch++;
//puts(G.CityName[j]);
}
printf("-->");
}
}
printf("结束\n");
}
if(0 == flags)
printf("\n\t\t警告:无此路径!\n");
/* //测试数据所用
for( int i = 0;i < G.vexnum; i++)
{
for( j = 0;j < G.vexnum;j++)
printf("%4d",P[i][j]);
printf("\n");
}
*/
printf("\n");
length = D[EndPoint];
if(length > 0)
{
printf("最短路长为:\t");
printf("%d\n",length);
}
/* //测试数据所用
for( i = 0;i < G.vexnum; i++)
{
printf("%4d",D[i]);
}
*/
printf("\n\n");
ReturnMenu();
LOOP3:
printf("请选择:\t");
p = getchar();
fflush(stdin);
if(p != 'Y' && p != 'y' && p != 'E' && p != 'e')
{
printf("\n\t\t警告:功能选择错误!!\n");
goto LOOP3;
}
system("cls");
}while(p == 'Y' || p == 'y');
if(p == 'e' || p == 'E')
exit(0);
}
/*--------------------------------------主函数---------------------------------------*/
void main()
{
mainprocess();
}
转载于:https://my.oschina.net/ucliaohh/blog/757954