您的位置:首页 > 其它

单源最短路径 --Dijkstra算法-通过边实现松弛

2016-04-27 19:07 302 查看
单源最短路径 --Dijkstra算法-通过边实现松弛

算法思想:

每次找到离源点最近的一个顶点,然后以该顶点为中心进行扩展,最终得到源点到其余所有点的最短路径

基本步骤如下:

1、将所有的顶点分为两部分:已知最短路程的顶点集合P和未知最短路径的顶点集合Q。最开始,已知最短路径的顶点集合P中只有源点一个顶点,我们这里用一个 book数组来记录哪些点在集合P中。例如对于某个顶点i,如果book[i]为1,则表示这个顶点在集合P中,如果book[i]为0则表示这个顶点在集合Q中。

2、设置源点s到自己的最短路径的为0,即dis[s]=0;若存在有源点能直接到达的顶点i,则把dis[i]设置为e[s][i]。同时把所有其他(源点不能直接到达的)顶点的最短路径设为正无穷。

3、在集合Q中的所有顶点中选择一个离源点s最近的顶点u(即dis[u]最小)加入到集合P。并考察所有以u为起点的边,对每一条边进行松弛操作。例如存在一条从u到v的边,那么可以通过将边u->v添加到尾部来拓展一条从s到v的路径,这条路径的长度是dis[u]+e[u][v]。如果这个值比目前已知的dis[v]的值要小,我们可以用新值来代替当前的dis[v]中的值。

4、重复第3步,如果集合Q为空,算法结束。最终dis数组中的值就是源点到所有的顶点的最短路径。

例如:

求顶点1到其他顶点的距离

第一行输入两个整数n和m。n表示顶点个数(编号1到n),

m表示边的条数。接下来m行,每行有3个数,

xyz,表示顶点x到顶点y边的权值为z。

input

6 9

1 2 1

1 3 12

2 3 9

2 4 3

3 5 5

4 3 4

4 5 13

4 6 15

5 6 4

output

0 1 8 4 13 17

#include<stdio.h>
int main(void)
{
int e[10][ 10],dis[10],book[10];
int i,j,n,m,t1,t2,t3;
int u,v,min;
int inf=99999999;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j)
{
e[i][j]=0;
}
else
{
e[i][j]=inf;
}
}
}
for(i=1;i<=m;i++)
{
scanf("%d %d %d",&t1,&t2,&t3);
e[t1][t2]=t3;
}
for(i=1;i<=n;i++)
{
dis[i]=e[1][i];
}
for(i=1;i<=n;i++)
{
book[i]=0;
}
book[1]=1;
//Dijkstra算法核心语句
for(i=1;i<=n-1;i++)
{
min=inf;
for(j=1;j<=n;j++)
{
if(book[j]==0&&dis[j]<min)
{
min=dis[j];
u=j;
}
}
book[u]=1;
for(v=1;v<=n;v++)
{
if(e[u][v]<inf)
{
if(dis[v]>dis[u]+e[u][v])
{
dis[v]=dis[u]+e[u][v];
}
}
}
}
for(i=1;i<=n;i++)
{
printf("%d ",dis[i]);
}
printf("\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: