Dijkstra算法

Posted mr94kevin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dijkstra算法相关的知识,希望对你有一定的参考价值。

Dijkstra算法是用于求单源最短路的算法,也就是求出一个点到图上其他点的最短路,但是要求图中不能有负边权,时间复杂度为O(n2)。

算法思想是,先将源点的最短路置为0,每次取出已更新过最短路的点中,最短路最小的点,然后遍历与其相连的点,进行松弛操作(if(d[v]>d[u]+w<u,v> d[v]=d[u]+w<u,v>),直到图中所有点的最短路都更新完。

显然算法可以优化,就是在取出最短路最小的点时,可以使用堆优化,复杂度大致降到O(mlogn),堆优化的Dijkstra是单源最短路无负边权时很好的选择,不会像SPFA那样被卡。

技术分享图片
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,s,eid,head[maxn],d[maxn],vis[maxn];
struct node { //自定义结构体,用于储存点的编号及其最短路
    int n,d;
    node(int n,int d):n(n),d(d) {}
    bool operator < (const node& rhs) const { //重载小于运算符,使得优先队列中
        return d>rhs.d; //最短路小的先出队
    }
};
priority_queue<node> q;
struct edge { //使用邻接表来储存图
    int v,w,next;
    edge(int v=0,int w=-1):v(v),w(w) {}
} E[maxm];
void init() { //记得初始化,包括邻接表的初始化和将d数组原先都置为inf
    memset(head,-1,sizeof(head));
    memset(d,inf,sizeof(d));
}
void insert(int u,int v,int w) {
    E[eid]=edge(v,w);
    E[eid].next=head[u];
    head[u]=eid++;
}
void dijkstra() {
    d[s]=0; //先将源点最短路置为0,并入队
    q.push(node(s,0));
    while(!q.empty()) {
        node i=q.top();
        q.pop();
        int u=i.n;
        if(vis[u]) continue; //每个结点只有一次会被用来更新其他结点
        vis[u]=1; //vis标志可避免结点重复扩展
        for(int p=head[u];p+1;p=E[p].next) { //遍历相连的结点
            int v=E[p].v;
            if(d[v]>d[u]+E[p].w) { //进行松弛操作,并将更新的结点入队
                d[v]=d[u]+E[p].w;
                q.push(node(v,d[v]));
            }
        }
    }
}
int main() {
    scanf("%d%d%d",&n,&m,&s);
    init();
    int u,v,w;
    for(int i=1;i<=m;++i) {
        scanf("%d%d%d",&u,&v,&w);
        insert(u,v,w);
    }
    dijkstra();
    for(int i=1;i<=n;++i) {
        if(i!=1) putchar( );
        printf("%d",d[i]);
    }
    return 0;
}
Dijkstra

需要注意的是,优先队列并不能动态修改结点的优先级(在此处就是最短路d),只能将新更新的结点入队,因此可能出现重复入队的情况。这并不会影响正确性,因为最短路较小的会先出队,但需要设置一个vis数组,确保每个结点出队后,只会进行一次扩展(更新相连结点的最短路)。

以上是关于Dijkstra算法的主要内容,如果未能解决你的问题,请参考以下文章

1.Dijkstra算法求解格栅地图路径matlab代码

1.Dijkstra算法求解格栅地图路径matlab代码

Dijkstra 算法伪代码混淆

Dijkstra算法A*算法D*算法LPA*算法和D* Lite算法详解汇总(原理matlab代码)格栅地图

Dijkstra算法A*算法D*算法LPA*算法和D* Lite算法详解汇总(原理matlab代码)格栅地图

Dijkstra算法A*算法D*算法LPA*算法和D* Lite算法详解汇总(原理matlab代码)格栅地图