图论浅析--最短路之Dijkstra

个人总结,欢迎拍砖~

最短路径:对有权图G=(V,E),从一个源点s到汇点t有很多路径,其中路径上权和最小的路径,称s到t的最短路径。
单源最短路径:求源点s到其它所有点的最短路径问题。

Dijkstra

计算某一顶点到其它所有顶点的最短路径。需注意权值不能为负。
通过为每个顶点 v 保留目前为止所找到的从s到v的最短路径来工作。
算法原理:贪心。
复杂度:O(n^2)。 可使用优先队列优化

算法思想

对已求点集合S
1、在未求点中找到一个到源点权和最小的点k,权和为lowcost[k]。
2、把点k加到集合S中,同时修改其余各点j的 lowcost[j],是否经过k后变短,若变短则更新。

if(lowcost[k]+g[k][j]<lowcost[j]) 
    lowcost[j]=g[k][j]+lowcost[k];

3、重复至更新完所有点。

过程演示

图6

步骤 v1 v2 v3 v4 v5 v6 v7 已选点集合S
1 (v1,0)** (v1,+∞) (v1,+∞) (v1,+∞) (v1,+∞) (v1,+∞) (v1,+∞) S={v1}
2 (v1,0)* (v1,3)** (v1,7) (v1,5) (v1,+∞) (v1,+∞) (v1,+∞) S={v1,v2}
3 (v1,0)* (v1,3)* (v2,5)** (v1,5) (v2,9) (v1,+∞) (v1,+∞) S={v1,v2,v3}
4 (v1,0)* (v1,3)* (v2,5)* (v1,5)** (v3,8) (v1,+∞) (v1,+∞) S={v1,v2,v3,v4}
5 (v1,0)* (v1,3)* (v2,5)* (v1,5)* (v3,8) (v4,7)** (v4,13) S={v1,v2,v3,v4,v6}
6 (v1,0)* (v1,3)* (v2,5)* (v1,5)* (v3,8)** (v4,7)* (v4,13) S={v1,v2,v3,v4,v6,v5}
7 (v1,0)* (v1,3)* (v2,5)* (v1,5)* (v3,8)* (v4,7)* (v6,9)** S={v1,v2,v3,v4,v6,v5,v7}

Code

int n; //图的点数
int g[NUM][NUM]; //图的邻接矩阵
int lowcost[NUM]; //到各点的最短距离
bool vis[NUM]; //访问标记
int pre[NUM]; //最短路的前驱节点
void Dijkstra(int beg)
{
    for(int i=0;i<n;i++)
    {
        lowcost[i]=INF;
        vis[i]=false;
        pre[i]=-1;
    }
    lowcost[beg]=0;
    for(int j=0;j<n;j++)
    {
        int k=-1;
        int Min=INF;
        for(int i=0;i<n;i++)
        {
            if(!vis[i] && lowcost[i]<Min)
            {
                Min=lowcost[i];
                k=i;
            }
        }
        if(k==-1)break;
        vis[k]=true;
        for(int i=0;i<n;i++)
        {
            if(!vis[i] && lowcost[k]+g[k][i]<lowcost[i])
            {
                lowcost[i]=lowcost[k]+g[k][i];
                pre[i]=k;
            }
        }
    }
}

附:wikipedia的Dijkstra算法演示

wikipedia的Dijkstra算法演示

版权声明:本文为博主原创文章,未经博主允许不得转载。

原文地址:https://www.cnblogs.com/wygdove/p/4814322.html