dijkstra算法心得

来源:互联网 发布:jquery 数组如何清空 编辑:程序博客网 时间:2024/06/08 18:15

基本思想

 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算)。 此外,引进两个集合S和U。S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离)。 初始时,S中只有起点s;U中是除s之外的顶点,并且U中顶点的路径是"起点s到该顶点的路径"。然后,从U中找出路径最短的顶点,并将其加入到S中;接着,更新U中的顶点和顶点对应的路径。 然后,再从U中找出路径最短的顶点,并将其加入到S中;接着,更新U中的顶点和顶点对应的路径。 ... 重复该操作,直到遍历完所有顶点。

操作步骤

(1) 初始时,S只包含起点s;U包含除s外的其他顶点,且U中顶点的距离为”起点s到该顶点的距离”[例如,U中顶点v的距离为(s,v)的长度,然后s和v不相邻,则v的距离为∞]。

(2) 从U中选出”距离最短的顶点k”,并将顶点k加入到S中;同时,从U中移除顶点k。

(3) 更新U中各个顶点到起点s的距离。之所以更新U中顶点的距离,是由于上一步中确定了k是求出最短路径的顶点,从而可以利用k来更新其它顶点的距离;例如,(s,v)的距离可能大于(s,k)+(k,v)的距离。

(4) 重复步骤(2)和(3),直到遍历完所有顶点。

单纯的看上面的理论可能比较难以理解,下面通过实例来对该算法进行说明。

迪杰斯特拉算法图解
这里写图片描述
例题:hdu最短路
题意送衣服,给你一定的点和点的值和权值,然后要你找到怎么最短送到终点。直接模版代入就行了

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int INF=200000000;const int maxnum = 105;const int maxint = 1001;int map[maxint][maxint];int vist[maxint],dow[maxint],ans[maxint];void dijkstra(int s,int n){    int i,j,k,minx;    memset(vist,0,sizeof(vist));    for(i=1;i<=n;i++)    {        ans[i]=map[s][i];    }    dow[s]=0;    vist[s]=1;    for(i=1;i<n;i++)//注意不能等于n,距离比点的数量少一    {        minx=INF;        for(j=1;j<=n;j++)        {            if(minx>ans[j]&&!vist[j])            {                minx=ans[j];//找出第一个最短点                k=j;            }        }        dow[k]=minx;        vist[k]=1;        for(j=1;j<=n;j++)        {            if(!vist[j]&&ans[j]>map[k][j]+dow[k])//找剩下的点的长度            {                ans[j]=map[k][j]+dow[k];            }        }    }}int main(){    // 记录图的两点间路径长度    int n, m;             // 图的结点数和路径数    while(scanf("%d %d", &n, &m) && (n || m))    {        int u, v, w;          // 输入p, q两点及其路径长度        for(int i=1; i<=n; ++i)            for(int j=1; j<=n; ++j)                map[i][j] =(i==j?0:INF);        for(int i=1; i<=m; ++i)        {            cin >> u>> v>> w;            map[u][v] =map[v][u] = w;      // q指向p,这样表示无向图        }        for(int i=1; i<=n; ++i)            ans[i] = maxint;        dijkstra(1,n);        cout << ans[n]<< endl;    }    return 0;}
0 0
原创粉丝点击