DeepSeek LeetCode 3123. 最短路径中的边 C++实现
以下是 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)
更多推荐





所有评论(0)