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

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

2个月前 (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. 明确标记不可达节点,符合题目输出要求。

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


原创内容 转载请注明出处

分享给朋友:

相关文章

用栈结构优雅破解括号匹配难题(力扣20题)

用栈结构优雅破解括号匹配难题(力扣20题)

一、题目重新解读给定一个仅包含 ('、')、'['、']'、'{'、'}' 的字符串,判断其是否有效。有效需满足:1....

【深度优先搜索实战】力扣547题:省份数量问题的图论解法

【深度优先搜索实战】力扣547题:省份数量问题的图论解法

题目解读‌我们面对的是一个典型的图论问题:给定一个城市的连接矩阵,需要计算其中相互连通的城市群(省份)数量。这个问题可以抽象为无向图中的连通分量计算,每个城市代表图中的一个节点,城市之间的连接关系代表...

力扣第44题:寻找两个正序数组的中位数 - 合并排序解法详解

力扣第44题:寻找两个正序数组的中位数 - 合并排序解法详解

内容简介本文详细解析了力扣第44题"寻找两个正序数组的中位数"的合并排序解法。通过双指针技术合并两个有序数组,然后直接计算合并后数组的中位数。虽然时间复杂度为O(m+n),但这种方...

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

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

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

洛谷1220题解:动态规划与区间DP优化解法(附代码注释)

洛谷1220题解:动态规划与区间DP优化解法(附代码注释)

一、题目解读洛谷1220题要求计算在n个位置放置灯的情况下,通过关闭连续区间灯并移动至区间端点,使得总耗电量最小。需考虑灯的功率与位置差异,设计高效的算法求解最优策略。二、解题思路1. 动态规划 +...

发表评论

访客

看不清,换一张

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