版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CSDN___CSDN/article/details/84593269
单源最短路径问题是指:对于给定的有向网络G=(V,E),求原点V0到其他顶点的最短路径。
按照长度递增的顺序逐步产生最短路径的方法,称为Dijkstra算法。
该算法的基本思想:
把图中的所有顶点分成两组,第一组包括已确定最短路径的顶点,初始时只含有一个源点,记为集合S;第二组包括尚未确定的最短路径的顶点,记为V-S。按最短路径长度递增的顺序逐个把V-S中的顶点加到S中去,直至从V0出发可以到达的所有顶点都包括到S中。在这个过程中,总保持V0到第一组S各顶点的最短路金都不大于从V0到第二组V-S的任何顶点的最短路径,第二组的顶点对应的距离是从V0到此顶点的只包括第一组S的顶点为中间顶点的最短路径长度。对于S中任意一点j,V0到j的路径长度皆小于V0到V-S中任意一点的路径的长度。
个人认为的关键步骤:
#include <stdio.h>
#include <stdlib.h>
const int FINITY = 5000;
const int M = 20;
int d[M];//最短路径向量
int p[M];//路径向量
typedef struct
{
char vexs[M];//顶点信息域
int edges[M][M];//邻接矩阵
int n,e;
}Mgraph;
void creat (Mgraph *g,int c)
{
int i,j,k,w;
FILE *f;
f=fopen("test.txt","r");
if(f)
{
fscanf(f,"%d%d",&g->n,&g->e);
for(i=0;i<g->n;i++)
fscanf(f,"%1s",&g->vexs[i]);
for(i=0;i<g->n;i++)//初始化
{
for(j=0;j<g->n;j++)
{
if(i==j) g->edges[i][j]=0;
else g->edges[i][j]=FINITY;
}
}
for(k=0;k<g->e;k++)
{
fscanf(f,"%d%d%d",&i,&j,&w);
g->edges[i][j]=w;
if(c==0) g->edges[j][i]=w;
}
fclose(f);
}
else
{
g->n=0;
}
}
void print(Mgraph g)
{
int i,j;
printf("%一共有%d个结点,%d条边\n",g.n,g.e);
for(i=0;i<g.n;i++)
{
for(j=0;j<g.n;j++)
{
printf("%-6d",g.edges[i][j]);
}
printf("\n");
}
}
void dijkstra (Mgraph g,int v0)
{
bool final[M];
int i,k,v,min;
//第一步 初始化集合S与距离向量d
for(v=0;v<g.n;v++)
{
final[v]=false;
d[v]=g.edges[v0][v];
if(d[v]<FINITY && d[v]!=0)
p[v]=v0;
else
p[v]=-1;//无前驱结点
}
d[v0]=0;
final[v0]=true;
//第二步 依次找出n-1个结点加入S中
for(i=1;i<g.n;i++)
{
min=FINITY;
for(k=0;k<g.n;k++)
{
if(!final[k] && d[k]<min)//!final[k] 表示k结点还在V-S中
{
v=k;
min=d[k];
}
}
printf("%c--%d\n",g.vexs[v],min);
if(min==FINITY) return ;
final[v]=true;
for(k=0;k<g.n;k++)
{
if(!final[k] && (min+g.edges[v][k])<d[k])
{
d[k]=min+g.edges[v][k];
p[k]=v;
}
}
}
}
void print_gpd(Mgraph g,int v0)//输出有向图的最短路径
{
int st[M],i,pre,top=-1;
for(i=0;i<g.n;i++)
{
printf("%c -> %c ",g.vexs[v0],g.vexs[i]);
printf("Distance : %3d ,path:",d[i]);
st[++top]=i;
pre=p[i];
while(pre!=-1)
{
st[++top]=pre;
pre=p[pre];
}
while(top>0)
{
printf("%2d",st[top--]);
}
printf("\n");
}
}
int main ()
{
int v0;
Mgraph g;
creat(&g,1);
print(g);
printf("请输入V0:\n");
scanf("%d",&v0);
dijkstra (g,v0);
print_gpd(g,v0);
return 0;
}