最短路径-一个顶点到各点(迪杰斯特拉算法)

来源:互联网 发布:unity3d能建模吗 编辑:程序博客网 时间:2024/04/28 03:46

//最短路径-一个顶点到各点(迪杰斯特拉算法)
#include<stdio.h>
////////////////////////////////////////////////
#define MAX 30
#define TRUE 1
#define FALSE 0
#define INFINITY 1000
typedef enum{DG,DN,UDG,UDN} Graphkind;
typedef struct arccell  //定义表示弧的邻接矩阵
{
 int adj; 
 int *info;  //弧的相关信息
}arccell,adjmatrix[MAX][MAX];
typedef struct  //定义一个图类型
{
 int vexs[MAX];  //存放顶点的值
 adjmatrix arcs;  //存放边
 int vexnum,arcnum;  //图中顶点和边的个数
 Graphkind kind;  //图的种类
}mgraph;
/////////////////////////////////////////////////

////////////////////////
typedef int pathmatrix[MAX][MAX]; 
typedef int shortpathtable[MAX];
///////////////////////


//找出值为v的顶点在图的存储数组中的索引
int locatevex(mgraph G,int v)
{
 for(int i=0;i<G.vexnum;++i)
  if(G.vexs[i]==v)return i;
}

int createDN(mgraph &G)    //构造有向网
{
 int i,j,k;
 int v1,v2,w;
  printf("输入有向网的顶点个数和边的个数:/n");
 scanf("%d%d",&G.vexnum,&G.arcnum);
 printf("输入有向网的各顶点的值:/n");
 for(i=0;i<G.vexnum;++i)
  scanf("%d",&G.vexs[i]);
 for(i=0;i<G.vexnum;++i) //初始化邻接矩阵
  for(j=0;j<G.vexnum;++j)
    {G.arcs[i][j].adj=INFINITY;G.arcs[i][j].info=0;}
 for(k=0;k<G.arcnum;++k)
 {
     printf("输入无向网边的两个关联顶点和边的权值:/n");
  scanf("%d%d%d",&v1,&v2,&w);
        i=locatevex(G,v1);
        j=locatevex(G,v2);
  G.arcs[i][j].adj=w;
 }
 return 1;
}

 

 

//求从v0到各个顶点的最短路径,用P返回路径,用D返回各路径的总权值
void shortpath_DJIK(mgraph G,int k,pathmatrix &P,shortpathtable &D)
{
 int v,v0,w,i,j;   
 int final[MAX]; //用此数组表示某个顶点是否已经并入s集合,其中final[i]表示G中索引为i的顶点
 v0=locatevex(G,k);//求数值为k的顶点在G中的索引
 for(v=0;v<G.vexnum;++v)
 {
       final[v]=FALSE; //初始化s集合为空集
    D[v]=G.arcs[v0][v].adj; //初始化D[i]为v0到i顶点的权
    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集
 //开始主循环
 for(i=1;i<G.vexnum;++i)
 {
    int min;
    min=INFINITY;  //给min赋一个较大的值以便比较
    for(w=0;w<G.vexnum;++w)
     if(!final[w])
      if(D[w]<min){v=w;min=D[w];}//求出距离v0顶点最近的顶点在G中的索引w,并把v0到它的权赋给D[w]
    final[v]=TRUE;  //将v顶点并入s集合
    for(j=0;j<G.vexnum;++j)
     if(!final[j]&&(min+G.arcs[v][j].adj<D[j]))
     {
      D[j]=min+G.arcs[v][j].adj;
      for(int h=0;h<G.vexnum;++h)P[j][h]=P[v][h];
      P[j][j]=TRUE;
     }
 }
}
//输出起点到各个顶点的最小长度和经过的顶点的函数
void print_DJIK(mgraph G,pathmatrix P,shortpathtable D)
{
 int i,j;
 for(i=0;i<G.vexnum;++i)
 {
  if(D[i]==1000)printf("/n从起点到顶点%d无最短路径/n",G.vexs[i]);
  else
  {
       printf("/n从起点到顶点%d的最短路径长度为:%d/n经过的顶点有:/n",G.vexs[i],D[i]);
      for(j=0;j<G.vexnum;++j)
      if(P[i][j]!=0)printf("%d ",G.vexs[j]);
  }
 }
}


void main()
{
 pathmatrix p;
 shortpathtable d;
 mgraph g1;  
 createDN(g1);
 shortpath_DJIK(g1,0,p,d);
 print_DJIK(g1,p,d);
}

 

 

 

原创粉丝点击