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日

相关文章

  • 浅谈angularJs函数的使用方法(大小写转换,拷贝,扩充对象)

    当然!下面是关于\”浅谈AngularJS函数的使用方法(大小写转换、拷贝、扩充对象)\”的完整攻略: 浅谈AngularJS函数的使用方法 在AngularJS中,有一些常用的函数可以用于大小写转换、拷贝和扩充对象。以下是两个示例: 示例1:大小写转换 在AngularJS中,可以使用 uppercase 和 lowercase 过滤器来进行大小写转换。 …

    other 2023年8月19日
    00
  • layerconfirm关闭事件

    以下是关于“layerconfirm关闭事件”的完整攻略: layerconfirm关闭事件 layerconfirm是一种常用的JavaScript弹窗插件,用于显示确认对话框。当用户点击确认或取消按钮时,layerconfirm会触发相应的事件。其中,关闭事件是指用户关闭对话框时触发的事件。如果您想在layerconfirm关闭事件中执行一些操作,可以按…

    other 2023年5月6日
    00
  • android应用内代码截屏(获取view快照)和禁止截屏

    Android应用内代码截屏(获取View快照)和禁止截屏 在Android开发中,有时候需要对应用内的某个视图进行截屏,或者禁止用户对应用进行截屏。本文将为您介绍如何在Android应用中实现视图截屏和禁止截屏功能。 获取View快照 在Android中,可以通过以下代码获取某个视图的快照: View view = findViewById(R.id.vi…

    其他 2023年3月28日
    00
  • Android Adapter里面嵌套ListView实例详解

    Android Adapter里面嵌套ListView实例详解 在Android开发中,我们经常需要在一个列表项中嵌套另一个列表项。这种情况下,我们可以使用ListView来实现嵌套列表的效果。本攻略将详细讲解如何在Android Adapter中嵌套ListView,并提供两个示例说明。 示例1:嵌套ListView的布局 首先,我们需要创建一个布局文件来…

    other 2023年7月28日
    00
  • pandas删除首列

    在pandas中,删除首列可以使用drop方法或iloc方法。以下是详细的攻略: 使用drop方法 使用drop方法可以删除指定的列。以下是删除首列的步骤: 读取数据。 python import pandas as pd df = pd.read_csv(‘data.csv’) 删除首列。 python df = df.drop(df.columns[0]…

    other 2023年5月7日
    00
  • ORACLE workflow审批界面显示附件信息和附件的下载链接(转)

    ORACLE workflow审批界面显示附件信息和附件的下载链接(转) 在ORACLE workflow流程中,有时需要在审批的界面中显示附件信息,并可以提供附件的下载链接。这篇文章将介绍如何实现这个需求。 实现步骤 创建一个新的Item Type 在WorkFlow Builder中,使用管理员账号登录,并选择File > New > Ite…

    其他 2023年3月28日
    00
  • Android内存优化杂谈

    Android内存优化杂谈攻略 1. 了解内存管理 在进行Android内存优化之前,首先需要了解Android的内存管理机制。Android系统使用Java虚拟机(JVM)来运行应用程序,而JVM使用垃圾回收机制来管理内存。了解内存管理机制可以帮助我们更好地优化内存使用。 2. 使用内存分析工具 使用内存分析工具可以帮助我们找出内存泄漏和内存占用过高的问题…

    other 2023年8月1日
    00
  • hive外部表详解以及案例演示

    Hive外部表详解以及案例演示 Hive是一个基于Hadoop的数据仓库工具,它提供了类似于SQL的查询语言HiveQL,可以将结化数据映射到Hadoop的分布式文件系统HDFS上。Hive支持部表和外部表,本攻略将详细介绍H外部表的概念、用法和案例演示。 1. 外部表的概念 外部表是指在Hive中定义的表,它的数据存储在HDFS上,但是表的元数据存储在Hi…

    other 2023年5月8日
    00
合作推广
合作推广
分享本页
返回顶部