codevs 2602 最短路径问题——良心题解

CodeVS 2602 最短路径问题——良心题解

题目描述

给定一个有向无环图,图的每个边都有一个代价,现在要求从起点 $S$ 出发,到达终点 $T$ 的最短路径和。请你求出最短路径和。

题解思路

首先需要明确的是,是有向无环图,因此可以使用拓扑排序来处理每个点的最短路径。同时题目要求求出最短路径和,因此可以使用 Djikstra 算法,使用小根堆来维护节点的优先级,即到起点的距离。

Djikstra 算法的基本思路是从起点出发,每次找到当前未访问节点中到起点距离最短的节点,然后遍历该节点的邻接节点,更新这些邻接节点到起点的距离。这个过程可以使用优先队列(小根堆)来实现,每次从优先队列中取出到起点距离最近的节点,然后更新其邻接节点的距离,再将这些邻接节点加入到优先队列中。

而本题中需要求出最短路径和,因此可以使用数组来记录起点到每个节点的最短路,然后在遍历过程中更新每个节点的最短路径和。

最后,需要注意的是当图中存在多个起点时,需要将所有起点入队,同时起点到起点的最短路初始化为0。

代码实现参见下方。

代码实现

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

const int N = 1e6 + 10;

int n, m;
int h[N], e[N], w[N], ne[N], idx;
int dist[N];
bool st[N];

void add(int a, int b, int c) {
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}

void dijkstra() {

    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> q;
    q.push({0, 1}); //起点为1,距离为0

    memset(dist, 0x3f, sizeof dist); //初始距离为无穷大
    dist[1] = 0;

    while (q.size()) {

        auto t = q.top();
        q.pop();

        int ver = t.second, distance = t.first;
        if (st[ver]) continue; //已确定最短距离,不需要再更新

        st[ver] = true;
        for (int i = h[ver]; i != -1; i = ne[i]) {
            int j = e[i];
            if (dist[j] > distance + w[i]) {
                dist[j] = distance + w[i];
                q.push({dist[j], j});
            }
        }
    }

    cout << dist[n] << endl;
}

int main() {

    cin >> n >> m;

    memset(h, -1, sizeof h);

    while (m -- ) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a, b, c);
    }

    dijkstra();

    return 0;
}

总结

本题是一道典型的最短路径问题,需要结合 Djikstra 算法和拓扑排序进行解决。同时需要注意当图中存在多个起点时,需要将所有起点入队,同时起点到起点的最短路初始化为0。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:codevs 2602 最短路径问题——良心题解 - Python技术站

(0)
上一篇 2023年3月28日
下一篇 2023年3月28日

相关文章

  • 在 linux 的命令行输出进度条

    要在 Linux 命令行实现输出进度条可以使用 pv 命令,下面是实现的具体步骤和示例。 步骤1:安装 pv 命令 在大多数 Linux 发行版中,可以通过包管理器直接安装 pv 命令。例如,在 Debian/Ubuntu 下可以使用以下命令安装: sudo apt-get install pv 如果你使用的是其他发行版,可以使用相应的包管理器安装 pv。 …

    other 2023年6月26日
    00
  • 如何使git工作通过tor将提交推送到github?

    以下是关于“如何使git工作通过tor将提交推送到github?”的完整攻略,包括基本知识和两个示例。 基本知识 Git是一种版本控制系统,它可以帮助用户管理和跟踪代码的变化。Tor是一种匿名网络,它可以帮助用户隐藏他们的IP地址和位置。通过将Git和Tor结合使用,用户可以匿名地提交和推送代码到GitHub。 以下是使Git工作通过Tor将提交推送到Git…

    other 2023年5月7日
    00
  • Win7旗舰版连接打印机报错0x00000002怎么办 错误代码0x00000002解决办法

    Win7旗舰版连接打印机报错0x00000002的解决办法 在连接打印机的时候,有部分用户可能会遇到Win7旗舰版连接打印机报错0x00000002的情况,即系统提示“无法连接到打印机,错误代码0x00000002”的错误信息,导致无法正常使用打印机。这种情况下,应该如何解决呢?下面我们提供一些解决方法。 方法一:删除打印机驱动 这种情况下,我们可以尝试删除…

    other 2023年6月27日
    00
  • Java @Accessors注解图文详解

    Java @Accessors注解是一种用于访问器方法的注解。该注解可简化访问器方法的生成,满足开发者对于代码简洁优美的要求。本文将对Java @Accessors注解进行详细讲解,内容包括注解的使用方法、示例说明以及优缺点分析。 一、Java @Accessors注解的使用方法 Java @Accessors注解需要在类上使用,其使用方式如下所示: imp…

    other 2023年6月25日
    00
  • Android中Fragment管理及重叠问题的解决方法

    关于“Android中Fragment管理及重叠问题的解决方法”的完整攻略,我将从以下三个方面进行详细讲解: Fragment的基本使用及其生命周期 Fragment管理及其相关API 解决Fragment重叠问题的方法 1. Fragment的基本使用及其生命周期 Fragment是一种可以嵌入到Activity中的组件,可以看作是Activity的一部分…

    other 2023年6月27日
    00
  • java解析xml字符串方法

    Java解析XML字符串方法 在Java开发中,解析XML字符串是一项常见的任务。本文将提供一个完整的攻略,介绍如何使用Java解析XML字符串,并提供两个示例说明。 步骤1:导入XML解析器 在开始解析XML字符串之前,需要导入XML解析器。Java提供了多种XML解析器,包括DOM、SAX和StAX。本文将使用DOM解析器作为示例。 可以使用以下代码导入…

    other 2023年5月8日
    00
  • java中string与date格式之间的转换

    Java中String与Date格式之间的转换 在Java中,String和Date是两种常用的数据类型。String类型用于表示字符串,而Date类型用于表示日期和时间。在实际开发中,我们经常需要将类型的日期转换为Date类型,或将Date类型的日期转换为String类型。本文将详细讲解Java中String与Date格式之间的换方法。 String转Da…

    other 2023年5月7日
    00
  • 算法打基础——HashⅡ: 全域哈希与完美哈希

    算法打基础——HashⅡ: 全域哈希与完美哈希 在算法打基础——HashⅠ: 哈希表一文中,我们介绍了哈希表这种数据结构的基本思想及其应用。然而,在实际应用中,哈希表也会遇到一些问题,例如哈希冲突和哈希函数不尽如人意等,这些问题会降低哈希表的效率和准确性,因此需要更加高效和安全的哈希方法来解决这些问题。 本文将介绍两种高效的哈希方法:全域哈希和完美哈希。 全…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部