单源最短路Dijkstra算法以及图解 详

迪杰斯特拉(Dijkstra)算法

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。

基本思想

     通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算)。

     此外,引进两个集合S和U。S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离)。

     初始时,S中只有起点s;U中是除s之外的顶点,并且U中顶点的路径是"起点s到该顶点的路径"。然后,从U中找出路径最短的顶点,并将其加入到S中;接着,更新U中的顶点和顶点对应的路径。 然后,再从U中找出路径最短的顶点,并将其加入到S中;接着,更新U中的顶点和顶点对应的路径。 ... 重复该操作,直到遍历完所有顶点。

核心思想

更新估算距离,松弛

 δ(u,v)≤δ(u,x)+δ(x,v)δ(u,v)≤δ(u,x)+δ(x,v)C(u,v)\leq C(u,x)+C(x,v)

算法图解

https://www.cnblogs.com/skywang12345/p/3711512.html

堆实现

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int Ni = 10000;
const int INF = 1 << 27;
struct node
{
    int point, value;
    // 构造
    node(int a, int b)
    {
        point = a;
        value = b;
    }
    // 重载<操作符
    bool operator<(const node &a) const
    {
        // 对小于运算符进行重载,如果两个值相等,那么继续判断point,如果不等,则返回false
        if (value == a.value)
        {
            return point < a.point;
        }
        else
        {
            return value > a.value;
        }
    }
};
vector<node> e[Ni];
int dis[Ni], n;
priority_queue<node> q;
void dijkstra();
int main()
{
    int a, b, c, m;
    scanf("%d%d", &n, &m);
    while (m--)
    {
        scanf("%d%d%d", &a, &b, &c);
        e[a].push_back(node(b, c));
        e[b].push_back(node(a, c));
    }
    
    // for (int i = 0; i <= n; i++)
    // {
    //     dis[i] = INF;
    // }
    memset(dis, 0x3f, sizeof(dis));
    dis[1] = 0;
    // 优先队列,队头元素最大,但是如果类型为struct需要重载<运算符
    q.push(node(1, dis[1]));

    dijkstra();

    for (int i = 1; i <= n; i++)
    {
        printf("%d ", dis[i]);
    }
    system("pause");
    return 0;
}
void dijkstra()
{
    while (!q.empty())
    {
        node x = q.top();
        q.pop();
        for (int i = 0; i < e[x.point].size(); i++)
        {
            node y = e[x.point][i];
            if (dis[y.point] > dis[x.point] + y.value)
            {
                dis[y.point] = dis[x.point] + y.value;
                q.push(node(y.point, dis[y.point]));
            }
        }
    }
}

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值