Dijkstra算法

来源:互联网 发布:网络棋牌室代理 编辑:程序博客网 时间:2024/05/29 14:47

本文简要介绍Dijkstra算法,该算法用于解决带权重的有向图上的单源最短路经问题,要求所有边的权重都是非负值。

  • 主要思想:
    该算法的主要思想是维护两个节点集合SVS,其中S中的点与源点之间的最短路径已经被找到,而VS是尚未找到最短路径的点的集合(其中V是所有节点的集合)。算法重复地从集合S中选取最短路径估计值最小的点u,并将u加入集合S,然后对所有从u出发的边进行松弛,直到所有点被加入集合S
  • 算法的初始化说明
    在该算法中,首先将源点加入集合S,并将源点的最短路径长度设置为0,而其它节点的最短路径估计设置为无穷大。
  • 实例
    本文使用 算法导论 一书中的实例来编程实现Dijkstra算法,实例如下图所示:
    这里写图片描述

  • 编程实现:

#include <iostream>using namespace std;int A[1000][1000];int dis[1000], Forward[1000];bool isSearch[1000];int i, j, k, len, source, destination, V, E;void dijkstra( int source){    //将源点加入已找到最短路的点的集合    //u也是连接已找到最短路点的集合和未找到最短路的点的集合的中介点    int u = source;    dis[u] = 0;    Forward[u] = 0;    isSearch[u] = 1;    //寻找与u邻接的点,并松弛相应的边    for(k = 1; k < V; k++)    {        for(i = 1; i < V; i++)        {            if(A[u][i] != 0x7fffffff && isSearch[i] == 0)            {            //松弛(u,i)这条边                if(dis[i] > dis[u] + A[u][i])                {                    dis[i] = dis[u] + A[u][i];                    Forward[i] = u;                }            }        }        //寻找新的u加入已找到最短路的点的集合        int ss = 0x7fffffff;        for(i = 0; i < V; i++)            if(isSearch[i] == 0 && dis[i] < ss)            {                ss = dis[i];                u = i;            }        isSearch[u] = 1;    }}void printPath(int Forward[], int source, int destination){    if(destination == source)        cout << source;    else    {        printPath(Forward, source, Forward[destination]);        cout << "->" << destination;    }}int main(){    cin >> V >> E >> source >> destination;//顶点数,边数, 源点, 目标点    for(i = 0; i < V; i++)        for(j = 0; j  < V; j++)            A[i][j] = 0x7fffffff;    for(i = 0; i < V; i++)        dis[i] = 0x7fffffff;    for(i = 0; i < V; i++)        Forward[i] = 0x7fffffff;    for(k = 0; k < E; k++)    {        cin >> i >> j >> len;        A[i][j] = len;    }    dijkstra(source);    cout << "the distance from " << source << " to " << destination << " is: " << dis[destination] << endl;    cout << "the path is: ";    printPath(Forward, source, destination);    cout << endl;    return 0;}
  • 结果如下:
    这里写图片描述