1- /* Implementation helpers for shortest_paths.hpp extras . */
1+ /* Path enumeration from PredDAG (resolve_to_paths) . */
22#include " netgraph/core/shortest_paths.hpp"
33
44#include < algorithm>
@@ -236,10 +236,12 @@ shortest_paths_core(const StrictMultiDiGraph& g, NodeId src,
236236 // Extract min-cost node from priority queue.
237237 // Structured binding: auto [d_u, neg_res_u, u] = ... destructures the tuple.
238238 auto [d_u, neg_res_u, u] = pq.top (); pq.pop ();
239- (void )neg_res_u; // Residual was only for tie-breaking in queue, not needed here
240239 if (u < 0 || u >= N) continue ;
241240 // Skip stale entries (node already processed at a lower cost).
242241 if (d_u > dist[static_cast <std::size_t >(u)]) continue ;
242+ // Skip residual-stale entries in single-path mode (same cost but outdated residual).
243+ if (!multipath && d_u == dist[static_cast <std::size_t >(u)] &&
244+ -neg_res_u < min_residual_to_node[static_cast <std::size_t >(u)] - kEpsilon ) continue ;
243245
244246 // Early exit optimization: record when we first reach destination.
245247 if (early_exit && u == dst_node && !have_best_dst) { best_dst_cost = d_u; have_best_dst = true ; }
@@ -311,7 +313,7 @@ shortest_paths_core(const StrictMultiDiGraph& g, NodeId src,
311313 selected_edges.clear ();
312314 selected_edges.push_back (static_cast <EdgeId>(best_edge_id));
313315 }
314- // Update distance and predecessors if we found a better path.
316+ // Update distance and predecessors if we found a better path (or equal-cost with better capacity) .
315317 if (!selected_edges.empty ()) {
316318 Cost new_cost = static_cast <Cost>(d_u + min_edge_cost);
317319 auto v_idx = static_cast <std::size_t >(v);
@@ -327,8 +329,10 @@ shortest_paths_core(const StrictMultiDiGraph& g, NodeId src,
327329 }
328330 Cap path_residual = std::min (min_residual_to_node[static_cast <std::size_t >(u)], max_edge_residual);
329331
330- // Relaxation: found shorter path to v.
331- if (new_cost < dist[v_idx]) {
332+ // Relaxation: found shorter path to v, or equal-cost path with better capacity (single-path mode).
333+ if (new_cost < dist[v_idx] ||
334+ (!multipath && new_cost == dist[v_idx] &&
335+ path_residual > min_residual_to_node[v_idx] + kEpsilon )) {
332336 dist[v_idx] = new_cost;
333337 min_residual_to_node[v_idx] = path_residual;
334338 pred_lists[v_idx].clear ();
0 commit comments