Dijkstra最短路径算法

Dijkstra算法简介

        Dijkstra算法是用于在加权有向图中找到单一起始点到其他所有点的最短路径的算法。它由荷兰计算机科学家艾兹赫尔·戴克斯特拉于1956年提出。

Dijkstra算法流程

        Dijkstra算法的核心思想是贪心算法,每次都选择距离起点最近的顶点,然后更新其邻接顶点的距离。

        在Dijkstra算法中,我们使用一个优先队列来存储所有顶点,按照距离起点的距离排序。我们同时使用一个距离数组dist来记录起点到各个顶点的最短距离。

Dijkstra算法的步骤如下:

  1. 初始化距离数组dist,其中dist[start] = 0,其他所有顶点的距离为无穷大。
  2. 将起点加入优先队列。
  3. 当优先队列非空时:
    • 从优先队列中取出距离起点最近的顶点u
    • 遍历u的所有邻接顶点v
      • 如果dist[u] + 边权(u, v) < dist[v],则更新dist[v],并将v加入优先队列。
  4. 重复步骤3,直到优先队列为空。

Dijkstra算法程序 

下面是Dijkstra算法的一个简化版的C++实现示例:

#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
// 优先队列,first是距离,second是顶点编号
priority_queue<pii, vector<pii>, greater<pii> > pq;
// 图的邻接表表示,graph[u]存储的是与顶点u相邻的所有顶点及其边权
vector<vector<pii> > graph;
// 距离数组,dist[i]表示起点到顶点i的最短距离
vector<int> dist;
// Dijkstra算法的实现
void dijkstra(int start) {
    dist[start] = 0; // 起点到起点的距离为0
    pq.push(make_pair(0, start)); // 将起点加入优先队列
    while (!pq.empty()) {
        int u = pq.top().second; // 当前顶点
        pq.pop();
        // 遍历所有与当前顶点相邻的顶点
        for (auto edge : graph[u]) {
            int v = edge.first; // 邻接顶点
            int w = edge.second; // 边的权重
            // 尝试更新邻接顶点的距离
            if (dist[u] + w < dist[v]) {
                dist[v] = dist[u] + w;
                pq.push(make_pair(dist[v], v));
            }
        }
    }
}
int main() {
    int n, m;
    cin >> n >> m; // 输入顶点数和边数
    graph.resize(n + 1);
    dist.resize(n + 1, INT_MAX); // 初始化距离数组为无穷大
    for (int i = 0; i < m; i++) {
        int u, v, w;
        cin >> u >> v >> w; // 输入边的两个顶点和权重
        graph[u].push_back(make_pair(v, w));
        // 注意:Dijkstra算法适用于有向图和无向图,但边的方向可能会影响算法的行为
    }
    int start = 1; // 选择1作为起点
    dijkstra(start);
    // 输出起点到各个顶点的最短距离
    for (int i = 1; i <= n; i++) {
        cout << "Shortest distance from " << start << " to " << i << ": " << dist[i] << endl;
    }
    return 0;
}

        在这个示例中,我们使用了C++的STL优先队列priority_queue来维护顶点,并用一个距离数组dist来记录最短距离。我们从起点开始,不断地更新其邻接顶点的距离,同时确保距离始终是最短的。

本结就到这里啦,感谢你的支持!

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值