Dijkstra重点看注意

 

/*要注意的地方有两个:
1.如果是动态确定的数作数组大小,则需要动态申请内存!!!
2.运行程序的时候严格按照输入的格式进行输入!!!*/

#include <stdio.h>
#include <stdlib.h>
#define MaxVertexNum 100       /*最大顶点数设为100*/
#define INFINITY 10000        /*设置一个大于所有边权值的一个边界值*/
typedef int VertexType;       /*顶点类型设为字符型*/
typedef int EdgeType;        /*边的权值设为整型*/
typedef struct{
 VertexType vexs[MaxVertexNum];     /*顶点表*/
 EdgeType edges[MaxVertexNum][MaxVertexNum];  /*邻接矩阵,即边表*/
 int n,e;          /*顶点数和边数*/
}MGragh;           /*MGragh是以邻接矩阵存储的图类型*/

typedef int PathMatrix;
typedef int ShortPathTable;

enum BOOL {FALSE = 0,TRUE = !FALSE};

void CreateMGraph(MGragh *G)
{
 int i,j,k,m,n;
 printf("请输入顶点信息(输入格式为:顶点数,边数):/n");
  scanf("%d %d",&(G->n),&(G->e));       /*输入顶点数和边数*/
 printf("请输入顶点信息(输入格式为:顶点号<CR>):/n");
 for (i = 0;i < G->n;i ++)        /*输入顶点信息,建立顶点表*/
 {
  scanf("%d",&(G->vexs[i]));
  //getchar();
 }
 for (i = 0;i < G->n;i ++)        /*初始化邻接矩阵*/
 {
  for (j = 0;j < G->n;j ++)
  {
   G->edges[i][j] = INFINITY;
  }
 }
 printf("请输入每条边对应的两个顶点的序号(输入格式为:i,j):/n");
 printf("请输入每条边对应的权值(输入格式为:i):/n");
 for (k = 0;k < G->e;k ++)        /*输入e条边,建立邻接矩阵*/
 {
  scanf("%d %d ",&m,&n);        /*若加入G->edges[j][i]=1;*/
  scanf("%d",&(G->edges[m][n]));     /*则为无向图的邻接矩阵存储建立*/
  //getchar();
 }
}/*CreateMGraph*/
void ShorttestPath(MGragh *G,int v0,PathMatrix *P,ShortPathTable *D)
{
 /*用Dijkstra算法求有向图G中存储序号为v0的顶点到其余顶点v的最短路径P[v]及其路径长度D[v]*/
 /*P[v]存放从v0到v的最短路径上v的前驱结点的序号.当v=v0时,P[v]的取值为-1*/
 /*当v!=v0,又无前驱结点时,P[v]的取值为-2*/
 /*final[v]为TRUE当且仅当v∈S,即已经求得从v0到v的最短路径*/
 /*常量INFINITY为边上权值可能的最大值*/
 VertexType v;
 int pre,Min;
 int i,w;
 BOOL *final;

 final = (BOOL *)malloc((G->n) * sizeof(BOOL));

 for (v = 0;v < G->n; ++ v)
 {
  final[v] = FALSE;
  D[v] = G->edges[v0][v];
  P[v0] = -1;           /*v0无前驱结点,将其前驱结点的值置为-1*/
  if (D[v]<INFINITY && v!=v0)
  {
   P[v] = v0;          
  }
  if (D[v] == INFINITY)
  {
   P[v] = -2;          /*当v距v0无限远时,将其前驱结点的值置为-2*/
  }
 }

 /*初始化,v0顶点属于S集*/
 D[v0] = 0;
 final[v0] = TRUE;

 /*开始主循环,每次求得v0到某个v顶点的最短路径,并加v到集合S*/
 for (i = 1;i < G->n; ++ i)
 {
  Min = INFINITY;
  for (w = 0;w < G->n; ++w)
  {
   if(!final[w])
    if (D[w] < Min)
    {
     v = w;
     Min = D[w];
    }
  }
  final[v] = TRUE;
  for (w = 0;w < G->n; ++ w)
  {
   if (!final[w] && (Min+G->edges[v][w] < D[w]))
   {
    D[w] = Min + G->edges[v][w];
    P[w] = v;
   }
  }
 }

 /*输出各最短路径的长度及路径上的结点*/
 for (i = 1;i < G->n;i ++)
 {
  if (P[i] == -2)
  {
   printf("max %d/n",i);
  }
  else
  {
   printf("%d %d",D[i],i);
   pre = P[i];
   while (pre > 0)
   {
    printf("←%d",pre);
    pre = P[pre];
   }
   printf("←0/n");
  }
 }

 free(final);
}


int main()
{
 MGragh *G = (MGragh *)malloc(sizeof(MGragh));
 CreateMGraph(G);
 PathMatrix *P;
 P = (PathMatrix *)malloc((G->n) * sizeof(PathMatrix));
 ShortPathTable *D;
 D = (ShortPathTable *)malloc((G->n) * sizeof(ShortPathTable));
 ShorttestPath(G,0,P,D);

 free(P);
 free(D);

 return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值