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

学习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不能处理有负权边的图。

你可能感兴趣的:(最短路,c++)