当前位置:首页 > 力扣 > 力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

5个月前 (06-25)

力扣3112题解法:带时间限制的最短路径问题解析(C++代码) 力扣 图论算法 Dijkstra算法 优先队列 C++ 第1张

一、题目解读

力扣3112题要求解决带时间限制的最短路径问题:给定一个有向图,节点具有消失时间,需计算从起点到各节点的最短路径,且路径总时间不能超过节点的消失时间。题目难点在于需在传统最短路径算法(如Dijkstra)中融入时间窗口判断,确保到达节点时未“消失”。此外,需处理无法到达的节点并标记为-1。

二、解题思路

1. 核心思想:采用Dijkstra算法框架,结合时间限制优化。通过优先队列维护“当前时间+节点”的最小堆,确保每次扩展最短路径的节点。

2. 关键步骤:

    构建邻接表存储带权边(节点+时间)。

    初始化距离数组,起点为0,其余INT_MAX。

    优先队列按时间排序,避免超时节点扩散。

    遍历邻接边时,判断新时间是否满足“未超时且更优”,更新距离并入队。

3. 优化点:

    跳过已超时节点(time > dist[u]),减少无效计算。

    无法到达节点标记为-1,避免INT_MAX误导。

三、解题步骤

1. 构建结构:使用vector<pair<int, int>>构建邻接表,存储双向边(u→v, t时间)。

2. 初始化:距离数组dist初始化为INT_MAX,起点dist[0]=0;优先队列pq加入(0, 0)。

3. 主循环:

    弹出堆顶(time, u),若time已超时(>dist[u]),跳过。

    遍历u的邻接节点(v, t):计算新时间new_time = time + t。

        若new_time < disappear[v](未超时)且更优,更新dist[v]并入队。

4. 后处理:将dist中仍为INT_MAX的节点置为-1,标记不可达。

四、代码及注释

class Solution {
public:
    vector<int> minimumTime(int n, vector<vector<int>>& edges, vector<int>& disappear) {
        // 构建邻接表
        vector<vector<pair<int, int>>> graph(n);
        for (const auto& edge : edges) {
            int u = edge[0], v = edge[1], t = edge[2];
            graph[u].emplace_back(v, t); // 双向边
            graph[v].emplace_back(u, t);
        }
        
        // 初始化距离数组
        vector<int> dist(n, INT_MAX);
        dist[0] = 0;
        
        // 最小堆,存储(到达时间, 节点)
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
        pq.emplace(0, 0);
        
        while (!pq.empty()) {
            auto [time, u] = pq.top(); pq.pop();
            
            // 跳过超时节点
            if (time > dist[u]) continue;
            
            // 遍历邻接节点
            for (const auto& [v, t] : graph[u]) {
                int new_time = time + t;
                
                // 检查时间限制并更新
                if (new_time < disappear[v] && new_time < dist[v]) {
                    dist[v] = new_time;
                    pq.emplace(new_time, v);
                }
            }
        }
        
        // 处理无法到达的节点
        for (int i = 0; i < n; ++i) {
            if (dist[i] == INT_MAX) {
                dist[i] = -1;
            }
        }
        
        return dist;
    }
};

注释说明:

● 邻接表双向存储节省时间复杂度。

● 优先队列按时间排序,确保扩展顺序正确。

● 超时判断避免无效路径扩散,提升效率。

● 最终标记不可达节点满足题目要求。

五、总结

本文解法通过融合Dijkstra算法与严格的时间窗口判断,高效解决了力扣3112题。关键点在于:

1. 优先队列维护时间顺序,避免超时节点污染结果。

2. 邻接表双向存储适应无向图特性,降低代码复杂度。

3. 明确标记不可达节点,符合题目输出要求。

该思路适用于有时间限制的最短路径问题,对算法优化与逻辑严谨性有较高要求,为同类题目提供通用解法模板。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣第92题:三步定位 精准反转链表指定区间

力扣第92题:三步定位 精准反转链表指定区间

题目解读给定一个单链表和两个整数left与right,要求将链表中从第left个节点到第right个节点的部分进行反转,而保持其他部分不变。例如,对于链表1→2→3→4→5,left=2,right=...

2017年 NOIP 提高组 逛公园(洛谷P3953)题解:代码解析与优化

2017年 NOIP 提高组 逛公园(洛谷P3953)题解:代码解析与优化

一、题目解读    2017年NOIP提高组“逛公园”题目(洛谷P3953)要求在有向图中计算从起点到终点满足特定条件的路径数量。题目难点在于处理路径长度限制与...

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

一、题目解读洛谷B3617题要求将输入的八进制字符串转换为十六进制表示。题目需处理大数场景,且对输入合法性有明确限制(长度不超过1000,仅包含0-7字符)。由于八进制与十六进制无法直接转换,需借助十...

牛客14496题解:括号最大深度问题(栈思想与代码优化)

牛客14496题解:括号最大深度问题(栈思想与代码优化)

一、题目解读牛客14496题要求计算给定括号字符串中的最大深度。例如,对于字符串 "(()())",最大深度为2。题目考察对括号嵌套结构的理解,以及如何通过编程找到最深嵌套层次。二...

【洛谷1184题解析】用C++高效解决地点匹配问题(附代码与解题思路)

【洛谷1184题解析】用C++高效解决地点匹配问题(附代码与解题思路)

一、题目解读洛谷1184题要求处理一组地点列表与行程记录,统计其中匹配的天数。题目难点在于高效处理带有空格的字符串输入,以及快速判断每日行程是否在高手可去地点集合中。需要兼顾输入格式解析与算法效率。二...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。