Dijkstra迪杰斯特拉

 

 

示例:图为G为:3个顶点,5条边。顶点v1,v2,v3;各边的权为

      <v1,v2>=4 , <v1,v3>=11 ,

      <v2,v1>=6 , <v1,v3>=2 ,

      <v3,v1>=6 。 

 

源代码:

 

#include<stdio.h>
#include<conio.h>

#define  OK                 1
#define  ERROR              -1
#define  NETWORK_INFINITY   32767
#define  MAX_VERTEX_NUM     12

 

typedef struct ArcCell {
   int  adj;
   //char *info;
}AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct {
   int  vexnum,arcnum;
   int  vexs[MAX_VERTEX_NUM];
   AdjMatrix   arcs;
}AMGraph;


int LocateVex( AMGraph G,int name )
{
   int ivex;
   for(ivex = 0;ivex < G.vexnum ;ivex ++)
     if(name == G.vexs[ivex])
       return ivex;
   return ERROR;
}

 

int CreateDN( AMGraph *G )      //创建有向网
{
   int i,j,k;   
   int v1,v2,w;
   printf("/n/n The Graph's number of Vertex :"); scanf("%d",&(G->vexnum));
   printf(" The Graph's number of Arcnum :");     scanf("%d",&(G->arcnum));
   printf("/n");

   /*顶点编号或者名称*/
   for(i = 0;i < G -> vexnum ;i ++){ printf(" The Graph's %d Vertex's NAME:",i+1); scanf("%d",(G->vexs)+i); }
   /*初始化邻接矩阵*/
   for(i=0;i< G->vexnum ;i++)
     for(j=0;j< G->vexnum ;j++){
   (G->arcs)[i][j].adj = NETWORK_INFINITY;
   if(i == j) (G->arcs)[i][i].adj = 0;
  }
   /* 构造邻接矩阵 */
   for(k = 0;k < G -> arcnum;k ++)
   {
     printf("/n The %d Arc ./n",k+1);
     printf(" The tail vertex:");do{ scanf("%d",&v1);if((v1<0)||(v1>G->vexnum))printf(" ERROR/n The tail vertex:"); }while((v1<0)||(v1>G->vexnum));
     printf(" The head vertex:");do{ scanf("%d",&v2);if((v2<0)||(v2>G->vexnum))printf(" ERROR/n The head vertex:"); }while((v2<0)||(v2>G->vexnum));
     printf(" The arc  weight:");scanf("%d",&w);
     i = LocateVex(*G,v1); j = LocateVex(*G,v2);
     (G->arcs)[i][j].adj = w;
     printf("/n");
   }
   return OK;
}


void ShortestPath_DIJ(AMGraph *G, int s_v, 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 v,w,i;
 int final[MAX_VERTEX_NUM];
 int min;

 for(v = 0; v < G->vexnum; v ++) {
  final[v] = false;
  d[v] = (G->arcs)[s_v][v].adj;
  for(w = 0; w < G->vexnum; w ++)
   p[v][w] = false;          //设空路径
  if(d[v] <= NETWORK_INFINITY){
   p[v][s_v] = true;
   p[v][v] = true;
  }
 }//for

 d[s_v] = 0; final[s_v] = true;     //初始化,v0顶点属于S集

    //开始主循环,每次求得v0到某个v顶点的最短路径,并加v到s集
 for(i = 1; i < G->vexnum; i ++){             //求其余G.vexnum - 1个顶点
  min = NETWORK_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].adj) < d[w]) ){
    d[w] = min + (G->arcs)[v][w].adj;
                //p[w] = p[v];      //修改路径
    for(int iw = 0;iw < G->vexnum; iw ++)
     p[w][iw] = p[v][iw];
    p[w][w] = true;

   }//if
 }//for
}

/*============================主函数main()====================================*/
int main( void )
{
   int i,j;
   int vexname;
   AMGraph G;
   //Dijkstra
   int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
   int ShortPathWeight[MAX_VERTEX_NUM];

   CreateDN( &G );    //创建有向网
   printf("The Adjacency Matrix is:/n");
   for(i = 0;i < G.vexnum;i ++){      //输出有向网G的邻接矩阵
     for(j = 0;j < G.vexnum;j ++)
       printf("%6d",G.arcs[i][j].adj);
     printf("/n");
   }

   vexname = G.vexs[0];  //求出从V0到其余顶点的最短距离,及其路径
   ShortestPath_DIJ(&G, LocateVex(G,vexname), PathMatrix, ShortPathWeight);

   printf("/n/nThe ShortPathTable is:/n");
   for(i = 0;i < G.vexnum;i ++){
     for(j = 0;j < G.vexnum;j ++)        //输出最短路径矩阵
       printf("%6d",PathMatrix[i][j]);     
     printf("/n");
   }

   printf("/n/nThe ShortPathTable and ShortDistance/n");
   for(i = 0; i<G.vexnum;i ++) {     //输出最短距离
    printf("<v%d,",G.vexs[0]);
    for(j = 1; j < G.vexnum; j ++)
     if(PathMatrix[i][j] && i!=j)
      printf("v%d,",G.vexs[j]);
    printf("v%d>:%-4d",G.vexs[i],ShortPathWeight[i]);
   }  
   printf("/n");

   getch();
   return 0;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值