/// Find the shortest path using Dijkstra algorithm from the \p start node to the \p goal node in the \p graph.
///
/// Whenever node is opened, \p f_user is called with two parameters (the opened node and value of currently shortest path).
///
/// \param graph to explore.
/// \param start initial node.
/// \param goal final node.
/// \param f_user function which is called for every open node with value of currently shortest path.
///
/// \returns pair where first := shortest path := distance of path, if there is no such path vector is empty and distance std::numeric_limits<edge_type:weight_type>::max().
///
/// \note TEdge of \p graph must follow graph::edge::WeightedEdge interface.
/// \sa graph::edge_type::WeightedEdge.
///
/// \throws std::out_of_range if \p graph contains an edge with a negative weight.
/// Find the shortest path using Dijkstra algorithm from the \p start node to the \p goal node in the \p graph.
/// This algorithm is run in both direction, from \p start and also from \p goal.
///
/// Whenever node is opened, \p f_user is called with two parameters (the opened node and value of currently shortest path).
///
/// \param graph to explore.
/// \param start initial node.
/// \param goal final node.
/// \param f_user function which is called for every open node with value of currently shortest path.
///
/// \returns pair where first := shortest path := distance of path, if there is no such path vector is empty and distance std::numeric_limits<edge_type:weight_type>::max().
///
/// \note TEdge of \p graph must follow graph::edge::WeightedEdge interface.
/// \sa graph::edge_type::WeightedEdge.
///
/// \throws std::out_of_range if \p graph contains an edge with a negative weight.