当前位置:编程学习 > C/C++ >>

图论之最短路径-------Dijkstra算法

Dijkstra算法(单源最短路径,其边的权值为非负数),其定义为以固定的一个顶点作为源点,求源点到其他顶点的最短路径。

一:

   集合S表示已经加入最短路径的顶点,集合T则表示未加入最短路径的顶点。

 

二:

  为了求源点v0到各个顶点vi的最段短路径需要设置3个数组,即S[n],path[n],dist[n];

 

  1.S[n]:S[i]=0时表示vi为加入到集合S中,S[i]=1则表示已经加入到集合S中的顶点。初始时S[v0]=1,其余的均为0.

2.path[n]:path[i]表示v0-->vi这条路径中vi的前一个顶点的序号。

3.dist[n]:dist[i]表示当前找到的v0-->vi的最短路径的长度,初始时dist[i]=Edge[v0][i].Edge[n][n]表示该图的邻接矩阵。

 

三:

 该算法需要做3个步骤:

 

1:在diat[n]中查找S[i]!=1,且dist[i]最小的顶点u.

2:将S[u]修改为1,表示u加入到集合S中。

3:修改T中每个顶点的vk的dist及path的值,当u--vk有边且Edge[u][k]<INF(INF为无穷大)且dist[u]+Edge[u][k]<dist[k]时,dist[k]=dist[u]+Edge[u][k],path[k]=u.

 

 

四:

 主要代码:

 

有向图为例:

#include<stdio.h>
#include<string.h>
#define MAXN 20
#define INF 1000000
int n;
int Edge[MAXN][MAXN];
int S[MAXN];
int dist[MAXN];
int path[MAXN];
void Dijkstra(int v0)
{
  int i,j,k;
 for(i=0;i<n;i++)//对s,dist,path进行初始化  关键步骤一
 {
  dist[i]=Edge[v0][i];
  S[i]=0;
  if(i!=v0&&dist[i]<INF)
   path[i]=v0;
  else
   path[i]=-1;
 }
 S[v0]=1;dist[v0]=0;//起初S集合中只有源点  特别注意
 for(i=0;i<n-1;i++)//查找最小路径的顶点u;  关键步骤二
 {
  int min=INF,u=v0;
  for(j=0;j<n;j++)
  {
   if(!S[j]&&dist[j]<min)
   {
    u=j;
    min=dist[j];
   }
  }
  S[u]=1;//表示找到的最小路径的顶点  特别注意呀
  for(k=0;k<n;k++)//对未加入最小路径的顶点的dist和path的值进行修改   关键步骤三
  {
   if(!S[k]&&Edge[u][k]<INF&&dist[u]+Edge[u][k]<dist[k])
   {
    dist[k]=dist[u]+Edge[u][k];
    path[k]=u;
   }
  }
 }
}
int main()
{
 int i,j;
 int u,v,w;
 scanf("%d",&n);
 while(1)
 {
  scanf("%d %d %d",&u,&v,&w);
  if(u==-1&&v==-1&&w==-1)
   break;
  Edge[u][v]=w;
 }
 for(i=0;i<n;i++)
 {
  for(j=0;j<n;j++)
  {
   if(i==j)
    Edge[i][j]=0;
   else if(Edge[i][j]==0)
    Edge[i][j]=INF;
  }
 }
 Dijkstra(0);
 int shortest[MAXN];//为了记录路径
 for(i=1;i<n;i++)
 {
  printf("%d\t",dist[i]);
  memset(shortest,0,sizeof(shortest));
  int k=0;
  shortest[k]=i;
  while(path[shortest[k]]!=0)
  {
   k++;
   shortest[k]=path[shortest[k-1]];
  }
  k++;
  shortest[k]=0;
  for(j=k;j>0;j--)
   printf("%d->",shortest[j]);
   printf("%d\n",shortest[0]);
 }
 return 0;
}


作者:No_Retreats
补充:软件开发 , C语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,