66 namespace tree_dp_detail
76 template <
class GT,
class SA>
84 static constexpr size_t NONE = std::numeric_limits<size_t>::max();
105 <<
"Tree_Topology: non-null root provided for empty graph";
117 Node *p = it.get_curr();
123 if (
root_ ==
nullptr)
127 <<
"Tree_Topology: root node is not part of the graph";
137 for (
size_t i = 0; i <
n_; ++i)
140 using Pair_Key = std::pair<size_t, size_t>;
146 Arc *a = it.get_curr_ne();
153 <<
"Tree_Topology: arc endpoint not indexed";
155 const size_t u =
si->second;
156 const size_t v =
ti->second;
158 <<
"Tree_Topology: self-loop detected";
160 Pair_Key key = u < v ? std::make_pair(u, v) : std::make_pair(v, u);
168 <<
"Tree_Topology: not a tree (expected " << (
n_ - 1)
172 it.has_curr(); it.next_ne())
174 const auto & [
fst,
snd] = it.get_curr();
175 const size_t u =
fst.first;
176 const size_t v =
fst.second;
189 for (
size_t i = 0; i <
n_; ++i)
195 for (
size_t i = 0; i <
n_; ++i)
207 visited(root_id) = 1;
208 stack.
push({root_id, 0});
212 auto &
fr = stack.
top();
230 <<
"Tree_Topology: graph is not connected";
233 for (
size_t i = 0; i <
n_; ++i)
237 for (
size_t j = 0; j <
children_(i).size(); ++j)
270 <<
"Tree_Topology::id_of: node not in graph";
278 <<
"Tree_Topology::node_of: id out of range";
331 template <
class GT,
typename T,
class SA = Dft_Show_Arc<GT>>
364 const size_t n =
topo_.size();
371 for (
size_t i = 0; i < n; ++i)
375 const auto & order =
topo_.post_order();
376 for (
size_t k = 0;
k < n; ++
k)
378 const size_t v = order[
k];
379 const size_t par =
topo_.parent(v);
414 return topo_.node_of(
id);
423 return topo_.id_of(node);
432 template <
class GT,
typename T,
class SA = Dft_Show_Arc<GT>>
460 template <
class GT,
typename T,
class SA = Dft_Show_Arc<GT>>
504 const size_t n =
topo_.size();
513 for (
size_t i = 0; i < n; ++i)
521 const auto & order =
topo_.post_order();
522 for (
size_t k = 0;
k < n; ++
k)
524 const size_t v = order[
k];
525 const size_t par =
topo_.parent(v);
535 for (
size_t k = n;
k-- > 0; )
537 const size_t v = order[
k];
541 const auto & children =
topo_.children(v);
542 const size_t nc = children.size();
547 for (
size_t j = 0; j <
nc; ++j)
549 const size_t c = children[j];
559 for (
size_t j = 0; j <
nc; ++j)
562 for (
size_t j =
nc; j-- > 0; )
568 for (
size_t j = 0; j <
nc; ++j)
570 const size_t c = children[j];
581 for (
size_t i = 0; i < n; ++i)
612 return topo_.node_of(
id);
621 return topo_.id_of(node);
630 template <
class GT,
typename T,
class SA = Dft_Show_Arc<GT>>
645 template <
class GT,
class SA = Dft_Show_Arc<GT>>
650 [](
auto *) ->
size_t {
return 1; },
651 [](
auto *,
const size_t &
acc,
auto *,
const size_t & child) ->
size_t
660 for (
size_t i = 0; i <
vals.size(); ++i)
678 template <
class GT,
class SA = Dft_Show_Arc<GT>>
683 [](
auto *) ->
size_t {
return 0; },
684 [](
const size_t & a,
const size_t & b) ->
size_t
686 return std::max(a, b);
688 [](
auto *,
auto *,
const size_t & v) ->
size_t {
return v + 1; },
693 for (
size_t i = 0; i <
vals.size(); ++i)
710 template <
class GT,
class SA = Dft_Show_Arc<GT>>
714 using P = std::pair<size_t, size_t>;
718 [](
auto *) ->
P {
return {1, 0}; },
719 [](
const P & a,
const P & b) ->
P
721 return {a.first + b.first, a.second + b.second};
723 [](
auto *,
auto *,
const P & v) ->
P
725 return {v.first, v.second + v.first};
731 for (
size_t i = 0; i <
vals.size(); ++i)
732 result(i) =
vals[i].second;
Exception handling system with formatted messages for Aleph-w.
#define ah_runtime_error_unless(C)
Throws std::runtime_error if condition does NOT hold.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
T & append(const T &data)
Append a copy of data
void reserve(size_t cap)
Reserves cap cells into the array.
Dynamic stack of elements of generic type T based on a singly linked list.
T & top()
Return a modifiable reference to the top item of the stack.
bool is_empty() const noexcept
Check if the stack is empty.
T pop()
Remove and return the top item of the stack.
T & push(const T &data)
Push an item by copy onto the top of the stack.
Generic key-value map implemented on top of a binary search tree.
typename Base::Iterator Iterator
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
Rerooting DP: O(n) computation of DP answer for all roots.
Array< T > dp_up_
Top-down contribution from parent side.
std::function< T(Node *)> Init_Fn
Initialization function: base contribution of a node.
std::function< T(const T &, const T &)> Merge_Fn
Merge function: associative binary operation to combine results.
Gen_Reroot_DP(const GT &g, Node *root, const T &identity, Init_Fn init, Merge_Fn merge, Apply_Edge_Fn apply_edge, SA sa=SA())
Construct and compute rerooting DP.
typename GT::Node Node
Node type.
Node * node_of(size_t id) const
Returns the node pointer for a given internal ID.
size_t id_of(Node *node) const
Returns the internal ID for a given node pointer.
Array< T > dp_down_
Bottom-up DP results.
Array< T > init_vals_
Cached per-node base values.
tree_dp_detail::Tree_Topology< GT, SA > topo_
Tree topology and order.
std::function< T(Node *, Node *, const T &)> Apply_Edge_Fn
Edge transformation function: applies edge effects to a subtree result.
Array< T > answer_
Final answer for each node as root.
const Array< T > & values() const noexcept
Returns all computed answers (indexed by internal ID).
size_t size() const noexcept
Returns the number of nodes in the tree.
T identity_
Identity for merge operation.
const T & value(Node *node) const
Returns the answer for a given node as root.
Generic bottom-up tree DP.
const Array< T > & values() const noexcept
Returns all DP values (indexed by internal node ID).
typename GT::Node Node
Node type.
Node * node_of(size_t id) const
Returns the node pointer for a given internal ID.
size_t id_of(Node *node) const
Returns the internal ID for a given node pointer.
Gen_Tree_DP(const GT &g, Node *root, Init_Fn init, Combine_Fn combine, SA sa=SA())
Construct and compute bottom-up DP.
size_t size() const noexcept
Returns the number of nodes in the tree.
Array< T > dp_
Computed DP values.
tree_dp_detail::Tree_Topology< GT, SA > topo_
Tree topology and order.
std::function< T(Node *, const T &, Node *, const T &)> Combine_Fn
Combine function: folds a child's value into the accumulator.
std::function< T(Node *)> Init_Fn
Initialization function: maps a leaf/node to its base value.
const T & value(Node *node) const
Returns the DP value for a given node.
Graph_Node< Node_Info > Node
The graph type.
Graph_Arc< Arc_Info > Arc
The node class type.
Filtered iterator on the nodes of a graph.
Extract tree topology: node indexing, adjacency, parent, order.
const Array< size_t > & children(size_t id) const
Returns children IDs of a node.
static constexpr size_t NONE
Sentinel for null/none parent or id.
size_t n_
Number of nodes.
const Array< size_t > & post_order() const noexcept
Returns post-order traversal (leaves first, root last).
Array< Array< size_t > > children_
Children list in the rooted tree.
Node * node_of(size_t id) const
Returns node pointer for a given ID.
const GT * graph_
Source graph.
size_t id_of(Node *node) const
Returns internal ID of a node.
typename GT::Arc Arc
Arc type.
void index_nodes()
Assign unique IDs to nodes and validate the root.
MapOLhash< Node *, size_t > node_to_id_
Mapping from node pointer to id.
Array< size_t > parent_
Parent id for each node.
Array< Node * > id_to_node_
Mapping from id to node pointer.
Node * root() const noexcept
Returns root node pointer.
void build_order()
BFS/DFS traversal to establish parent-child relations and order.
size_t parent(size_t id) const noexcept
Returns parent ID of a node.
size_t size() const noexcept
Returns number of nodes.
void build_adjacency()
Build undirected adjacency list and verify tree properties.
Array< size_t > order_
Post-order traversal (leaves first).
const Array< Node * > & nodes() const noexcept
Returns all node pointers indexed by ID.
Tree_Topology(const GT &g, Node *root, SA sa=SA())
Preprocess tree topology.
typename GT::Node Node
Node type.
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
__gmp_expr< T, __gmp_binary_expr< __gmp_expr< T, U >, unsigned long int, __gmp_root_function > > root(const __gmp_expr< T, U > &expr, unsigned long int l)
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
Array< size_t > tree_subtree_sizes(const GT &g, typename GT::Node *root, SA sa=SA())
Compute subtree sizes for every node.
static void suffix(Node *root, DynList< Node * > &acc)
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
std::decay_t< typename HeadC::Item_Type > T
static void prefix(Node *root, DynList< Node * > &acc)
Itor3 merge(Itor1 source1Beg, Itor1 source1End, Itor2 source2Beg, Itor2 source2End, Itor3 destBeg)
Merge two sorted ranges.
Array< size_t > tree_max_distance(const GT &g, typename GT::Node *root, SA sa=SA())
Compute the maximum distance from each node to any leaf.
Array< size_t > tree_sum_of_distances(const GT &g, typename GT::Node *root, SA sa=SA())
Compute sum of distances from each node to all others.
static std::atomic< bool > init
Filtered iterator on all the arcs of a graph.
Open addressing hash map using linear probing.
Data & find(const Key &key)
Find and return the value for a key.
Pair * insert(const Key &key, const Data &data)
Insert a key-value pair (copy semantics).
Pair * search(const Key &key) const noexcept
Search for a key in the map.
Dynamic array container with automatic resizing.
Dynamic stack implementation based on linked lists.
Dynamic map with open hashing.
Dynamic key-value map based on balanced binary search trees.
Generic graph and digraph implementations.