@@ -230,28 +230,29 @@ shortest_paths_core(const StrictMultiDiGraph& g, NodeId src,
230230
231231 std::vector<std::uint32_t > seen (static_cast <std::size_t >(N), 0u );
232232 std::uint32_t seen_token = 0u ;
233+ std::vector<NodeId> dfs_stack;
234+ dfs_stack.reserve (16 );
233235 auto parent_reaches_child_via_pred_links = [&](NodeId parent, NodeId child) {
234236 if (parent == child) return true ;
235237 ++seen_token;
236238 if (seen_token == 0 ) {
237239 std::fill (seen.begin (), seen.end (), 0 );
238240 seen_token = 1 ;
239241 }
240- std::vector<NodeId> st;
241- st.reserve (16 );
242- st.push_back (parent);
242+ dfs_stack.clear ();
243+ dfs_stack.push_back (parent);
243244 seen[static_cast <std::size_t >(parent)] = seen_token;
244- while (!st .empty ()) {
245- NodeId cur = st .back ();
246- st .pop_back ();
245+ while (!dfs_stack .empty ()) {
246+ NodeId cur = dfs_stack .back ();
247+ dfs_stack .pop_back ();
247248 if (cur == child) return true ;
248249 for (const auto & pr : pred_lists[static_cast <std::size_t >(cur)]) {
249250 NodeId p = pr.first ;
250251 if (p < 0 || p >= N) continue ;
251252 auto p_idx = static_cast <std::size_t >(p);
252253 if (seen[p_idx] == seen_token) continue ;
253254 seen[p_idx] = seen_token;
254- st .push_back (p);
255+ dfs_stack .push_back (p);
255256 }
256257 }
257258 return false ;
@@ -383,9 +384,10 @@ shortest_paths_core(const StrictMultiDiGraph& g, NodeId src,
383384 }
384385 // Multipath: found equal-cost alternative path to v.
385386 else if (multipath && new_cost == dist[v_idx]) {
386- // Guard against zero-cost predecessor cycles by rejecting additions
387- // that would introduce a cycle in predecessor relations.
388- if (!parent_reaches_child_via_pred_links (u, v)) {
387+ // With non-negative edge costs, predecessor cycles can only arise on
388+ // zero-cost equal-distance tiers. Keep the cycle guard only for that
389+ // case to minimize overhead in typical positive-cost topologies.
390+ if (min_edge_cost != 0 || !parent_reaches_child_via_pred_links (u, v)) {
389391 pred_lists[v_idx].push_back ({u, std::move (selected_edges)});
390392 }
391393 // Note: In multipath mode, we don't update min_residual_to_node because
0 commit comments