dijkstra算法及一些最短路的注意事项

来源:互联网 发布:mysql安装包下载 64位 编辑:程序博客网 时间:2024/04/28 07:10

学习dijkstra已经一周了,学完之后没有温习,以至于今天做题的时候忘了。

当做温习一下吧。


讲一讲dijkstra的主要做法吧。

我们用一个数组s 去存储最短路径上的点(实际上还有标记某点是否被访问的作用)。

还需要用一个dis数组,去储存从起点到某个点的最小距离。(dis[ j ] 就表示从起点到 j 的最短距离)。

如果要求输出路径,我们还可以用一个poineer数组,去记录最短路上某个点的先驱顶点。(其实最好是用栈存放,便于打印路径)


设起点为start , 图用邻接矩阵 matrix[ ][ ] 储存。 

我们从起点出发,首先将所有与起点相连的边存在dis数组里。(毫无疑问,起点到 i 的最短距离就是 matrix[ start ][ i ])

然后我们寻找与start相连的最短路。假设为 k, 然后我们以  k 为中间点寻找最短路。若从 start  -> k + k ->j  <  start ->j, 我们就更新start -> j 的最小距离  。

重复上一步,直到所有顶点都被标记。


此时我们得到的dis数组是一个从 start 出发,到其他所有顶点的最短路。



void dijkstra(int start)//int matrix[][], int poineer[][], int dis[]->这些都可以设为全局变量, int f,f为顶点数{    for(int i = 1; i <= f; i++)    {        dis[i] = matrix[start][i];        s[i] = false;        if(matrix[start][i] < INF)        {            poineer[i] = start;        }        else            poineer[i] = -1;    }    int pos;    s[start] = 1;    dis[start] = 0;    for(int i = 1; i < f; i++)    {        int min = INF;        for(int j = 1; j <= f; j++)        {            if(!s[j] && dis[j] < min)            {                   pos = j;                   min = dis[j];            }        }        s[pos] = true;        for(int j = 1; j <= f; j++)        {            if(!s[j] && matrix[pos][j] < INF)                if(matrix[pos][j] + dis[pos] < dis[j])                {                    poineer[j] = pos;                    dis[j] = dis[pos] + matrix[pos][j];                }        }    }}


接下来讲讲一些注意事项:

1. 给出 从 i - > j 的直接路可能不只一条,我们在储存的时候需要存储最小的那条路。

2.需要进行特殊判断:(1)起点和终点可能根本没有出现(hdu 2112),这个当然是不可达的。(2)起点和终点相同,直接输出0。

3.注意的有向图还是无向图。

4.dijkstra不能处理有负权边的图。

0 0
原创粉丝点击