以下是 LeetCode 3123 "最短路径中的边" 的 C++ 实现:

```cpp
class Solution {
public:
    vector<bool> findAnswer(int n, vector<vector<int>>& edges) {
        int m = edges.size();
        
        // 建图:邻接表存储 (邻居, 权重, 边的索引)
        vector<vector<tuple<int, int, int>>> graph(n);
        for (int i = 0; i < m; i++) {
            int u = edges[i][0], v = edges[i][1], w = edges[i][2];
            graph[u].emplace_back(v, w, i);
            graph[v].emplace_back(u, w, i);
        }
        
        // 从 0 出发的最短距离
        vector<long long> dist0 = dijkstra(n, graph, 0);
        // 从 n-1 出发的最短距离
        vector<long long> dist1 = dijkstra(n, graph, n - 1);
        
        long long shortest = dist0[n - 1];
        
        vector<bool> ans(m, false);
        // 如果不连通,直接返回
        if (shortest == LLONG_MAX) return ans;
        
        for (int i = 0; i < m; i++) {
            int u = edges[i][0], v = edges[i][1], w = edges[i][2];
            // 检查该边是否在至少一条最短路径上
            if (dist0[u] != LLONG_MAX && dist1[v] != LLONG_MAX &&
                dist0[u] + w + dist1[v] == shortest) {
                ans[i] = true;
            } else if (dist0[v] != LLONG_MAX && dist1[u] != LLONG_MAX &&
                       dist0[v] + w + dist1[u] == shortest) {
                ans[i] = true;
            }
        }
        
        return ans;
    }
    
private:
    vector<long long> dijkstra(int n, vector<vector<tuple<int, int, int>>>& graph, int start) {
        vector<long long> dist(n, LLONG_MAX);
        dist[start] = 0;
        
        // 小顶堆:存储 (距离, 节点)
        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;
        pq.emplace(0, start);
        
        while (!pq.empty()) {
            auto [d, u] = pq.top();
            pq.pop();
            
            if (d > dist[u]) continue;
            
            for (auto& [v, w, _] : graph[u]) {
                long long nd = d + w;
                if (nd < dist[v]) {
                    dist[v] = nd;
                    pq.emplace(nd, v);
                }
}
        }
        
        return dist;
    }
};
```

核心思路说明:

1. 双向 Dijkstra:
   · 分别从节点 0 和节点 n-1 运行 Dijkstra 算法
   · 得到每个节点到起点的最短距离 dist0 和到终点的最短距离 dist1
2. 判断最短路径边:
   · 全局最短距离 shortest = dist0[n-1]
   · 对于边 (u, v, w),若满足:
     · dist0[u] + w + dist1[v] == shortest,或
     · dist0[v] + w + dist1[u] == shortest
   · 则说明这条边在某条最短路径上
3. 注意事项:
   · 使用 long long 防止整数溢出
   · 使用 LLONG_MAX 表示不可达
   · 需要提前检查是否连通,若不连通直接返回全 false

复杂度分析:

· 时间复杂度:O((n + m) log n)
· 空间复杂度:O(n + m)

 

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐