Dijkstra求单源最短路——详细注释

如果是无向图,只需要变更 G[a][b] = min(G[a][b], c);

变为G[a][b] = G[b][a] = min(G[a][b],c);

#include <iostream>
#include <algorithm>

using namespace std;

const int MAXN = 1005; // 定义最大节点数
const int INF = 1e9;   // 定义无穷大,用于表示两个节点之间没有边

int G[MAXN][MAXN];  // 定义图的邻接矩阵表示,G[i][j]表示节点i到节点j的边的权值
int dist[MAXN];     // 定义数组dist,dist[i]用于存储源节点到节点i的最短距离
bool visited[MAXN]; // 定义数组visited,visited[i]用于标记节点i是否已经被访问

// Dijkstra算法函数,参数s表示源节点,n表示节点总数
void Dijkstra(int s, int n)
{
    // 初始化最短距离为无穷大
    for (int i = 1; i <= n; i++)
    {
        dist[i] = INF;
    }
    // 源节点到自己的最短距离为0
    dist[s] = 0;

    // 主循环,每次找到一个最短路径节点
    for (int i = 1; i <= n; i++)
    {
        int u = -1, MIN = INF;

        // 下面的for循环是在未访问的节点中找到最短路径最小的节点
        //(1)它的目的是在所有未被访问过的节点中,找到一个从源节点出发的最短路径长度最小的节点。
        //(2)具体来说,我们维护一个dist数组,其中dist[i]表示从源节点到节点i的最短路径长度。在每一轮循环中,我们遍历所有未被访问过的节点,找到dist值最小的节点,然后将这个节点标记为已访问。
        //(3)这个步骤的目的是确保我们总是先处理离源节点最近的节点,这样我们就可以保证,当我们访问一个节点时,我们已经找到了从源节点到这个节点的最短路径。这是Dijkstra算法的贪心策略:总是先处理最“近”的节点。
        for (int j = 1; j <= n; j++)
        {
            if (!visited[j] && dist[j] < MIN)
            {
                u = j;
                MIN = dist[j];
            }
        }
        // 如果找不到这样的节点,说明剩下的节点都不可达,直接返回
        if (u == -1)
            return;
        // 标记节点u为已访问
        visited[u] = true;

        // 更新通过节点u可以缩短的路径
        //(1)如果v已经被访问过,那么我们就跳过它,因为我们已经找到了从源节点到v的最短路径。
        //(2)如果节点u到节点v之间没有边(即G[u][v]等于无穷大),那么我们也跳过它,因为我们不能通过u到达v。
        //(3)如果从源节点到节点u的最短路径长度(dist[u])加上从节点u到节点v的边的权值(G[u][v])小于当前从源节点到节点v的最短路径长度(dist[v]),那么我们就找到了一条更短的路径,于是更新dist[v]。
        for (int v = 1; v <= n; v++)
        {
            if (!visited[v] && G[u][v] != INF && dist[u] + G[u][v] < dist[v])
            {
                dist[v] = dist[u] + G[u][v];
            }
        }
    }
}

int main()
{
    int n, m;
    cin >> n >> m;
    // 初始化图的邻接矩阵为无穷大,表示所有节点之间都不可达
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            G[i][j] = INF;
        }
    }
    // 读入边的信息,并更新邻接矩阵
    for (int i = 0; i < m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        G[a][b] = min(G[a][b], c); // 有向图,只添加一条从a到b的边
    }
    // 调用Dijkstra算法计算最短路径
    Dijkstra(1, n);
    // 输出从1号点到n号点的最短路径长度
    cout << dist[n] << endl;
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值