最短路径算法

#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();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值