最短路 迪杰斯特拉.cpp

<span style="color:#3333ff;">#include<stdio.h>
#include<stdlib.h>
#define INITITY 999//最大值
#define VERTEX 20//最多顶点个数
#define FALSE 0
#define TURE 1
#define size 30
#define OVERFLOW -1

typedef struct ArcCell{
   int adj;//权值类型
}ArcCell,AdjMatrix[VERTEX][VERTEX];

typedef struct{
  char vexs[20];//顶点向量
  AdjMatrix arcs;//邻接矩阵
  int vexnum,arcnum;//图的当前顶点数和弧数
}MGraph;

typedef struct{
  char *top,*base;//栈顶指针,栈尾指针
}Stack;

int P[20][20];
void InitStack(Stack *S)//初始化栈
{
   S->base=(char *)malloc(VERTEX*sizeof(char));
   S->top=S->base;
}

void DestoyStock(Stack *S)//销毁栈
{
  S->top=S->base;
}

void PushStack(Stack *S,char a)//元素压栈
{
 if(S->top-S->base>size)
    exit(OVERFLOW);
  else *S->top++=a;
}

void PrintfStack(Stack *S)//输出栈
{
 if(S->top==S->base)
    exit(OVERFLOW);
    printf("%c",*--S->top);
  while(S->top!=S->base)
    printf("->%c",*--S->top);

}

int Located(MGraph *G,char v1)//寻找顶点v1的位置
{ int i;
   for(i=1;i<=G->vexnum;i++)
	 if(G->vexs[i]==v1) return i;
}

void CreateUDN(MGraph *G){
   int i,j,k,w;
    char v1,v2;
   printf("请输入图的顶点数:");
     scanf("%d",&G->vexnum);getchar();
  for(i=1;i<=G->vexnum;i++)
        G->vexs[i]=0;//顶点向量置零
   for(i=1;i<=G->vexnum;i++){
      printf("请输入第%d个顶点:",i),
      scanf("%c",&G->vexs[i]),getchar();//构造顶点向量
      }
   for(i=1;i<=G->vexnum;i++)
      for(j=1;j<=G->vexnum;j++)
		    G->arcs[i][j].adj=999;//邻接矩阵初始化
   printf("请输入图的弧数:");
      scanf("%d",&G->arcnum);getchar();
   for(k=1;k<=G->arcnum;k++)
     {
       printf("请输入第%d条弧向量<v1,v2,weight>:",k);
        scanf("%c,%c,%d",&v1,&v2,&w);getchar();
        i=Located(G,v1); j=Located(G,v2);//查找位置
        G->arcs[i][j].adj=w;//更新权值最小
        G->arcs[j][i]=G->arcs[i][j];
   }
}

void ShortestPath_DIJ(MGraph *G,int u,int *D)//求最短路径,迪杰斯特拉算法
{int final[VERTEX],v,w,i,min,k=1;
   for(v=1;v<=G->vexnum;v++)
     {
       final[v]=FALSE;D[v]=G->arcs[u][v].adj;
       for(w=1;w<=G->vexnum;w++)
         P[v][w]=FALSE;//设空路径
     }
        D[u]=0,final[u]=FALSE;//初始化,u属于S
      for(i=1;i<=G->vexnum;i++){//开始主循环,每一次求得u到其他顶点的最短路径
        min=INITITY;//当前所知的离u顶点的最短距离
        for(w=0;w<=G->vexnum;w++)
           if(!final[w])//w顶点在V-S中
              if(D[w]<min){//w顶点离u更近
                 v=w;min=D[w];
                 }
        final[v]=TURE;//离u更近的v加入中
        for(w=0;w<=G->vexnum;w++)//更新当前最短路径及距离
           if(!final[w]&&(min+G->arcs[v][w].adj<D[w])){//修改D[w]和P[w]
           D[w]=min+G->arcs[v][w].adj;
           P[u][w]=v;P[w][u]=v;
           }
         }
}

int main()
{  int j,u,D[20],a;
   MGraph G;
   Stack S;InitStack(&S);//初始化栈
   CreateUDN(&G);
   printf("
****************************最短路径************************************
");
   for(u=1;u<G.vexnum;u++){
	   printf("以%c为起点:
",G.vexs[u]);
    ShortestPath_DIJ(&G,u,D);//求最短路径
    for(j=u+1;j<=G.vexnum;j++){
     printf("    %c->%c的最短路径为:",G.vexs[u],G.vexs[j]);
       if(P[u][j]==0)//如果P[u][j]=0,则两点之间的最短路径是直达的,只输出两个顶点即可
          printf("%c->%c",G.vexs[u],G.vexs[j]),
          printf("    权值:%d ",D[j]),printf("
");
       else{//不是直达,则将其所经节点依次存入栈中,最后输出
         PushStack(&S,G.vexs[j]);
         a=P[u][j];//a=0,则u与j之间是直达的,否则之间还经过其他的节点
         while(a!=0)//中间所经节点依次压入栈中
         {
           PushStack(&S,G.vexs[a]);
           a=P[u][a];
         }
           PushStack(&S,G.vexs[u]);//将起始节点压入栈中
           PrintfStack(&S);
           printf("    权值:%d ",D[j]);printf("
");
           DestoyStock(&S);}
       }
      }
  return 0;
}
</span>


原文地址:https://www.cnblogs.com/codeyuan/p/4254546.html