/* -*- mode: C++; indent-tabs-mode: nil; -*-
* This file is a part of LEMON, a generic C++ optimization library.
* Copyright (C) 2003-2008
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
* (Egervary Research Group on Combinatorial Optimization, EGRES).
* Permission to use, modify and distribute this software is granted
* provided that this copyright notice appears in all copies. For
* precise terms see the accompanying LICENSE file.
* This software is provided "AS IS" with no warranty of any kind,
* express or implied, and with no claim as to its suitability for any
#ifndef LEMON_MIN_COST_ARBORESCENCE_H
#define LEMON_MIN_COST_ARBORESCENCE_H
///\brief Minimum Cost Arborescence algorithm.
#include <lemon/list_graph.h>
#include <lemon/bin_heap.h>
#include <lemon/assert.h>
/// \brief Default traits class for MinCostArborescence class.
/// Default traits class for MinCostArborescence class.
/// \param GR Digraph type.
/// \param CM Type of cost map.
template <class GR, class CM>
struct MinCostArborescenceDefaultTraits{
/// \brief The digraph type the algorithm runs on.
/// \brief The type of the map that stores the arc costs.
/// The type of the map that stores the arc costs.
/// It must meet the \ref concepts::ReadMap "ReadMap" concept.
/// \brief The value type of the costs.
/// The value type of the costs.
typedef typename CostMap::Value Value;
/// \brief The type of the map that stores which arcs are in the
/// The type of the map that stores which arcs are in the
/// arborescence. It must meet the \ref concepts::WriteMap
/// "WriteMap" concept. Initially it will be set to false on each
/// arc. After it will set all arborescence arcs once.
typedef typename Digraph::template ArcMap<bool> ArborescenceMap;
/// \brief Instantiates a \c ArborescenceMap.
/// This function instantiates a \c ArborescenceMap.
/// \param digraph is the graph, to which we would like to
/// calculate the \c ArborescenceMap.
static ArborescenceMap *createArborescenceMap(const Digraph &digraph){
return new ArborescenceMap(digraph);
/// \brief The type of the \c PredMap
/// The type of the \c PredMap. It is a node map with an arc value type.
typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
/// \brief Instantiates a \c PredMap.
/// This function instantiates a \c PredMap.
/// \param digraph The digraph to which we would like to define the
static PredMap *createPredMap(const Digraph &digraph){
return new PredMap(digraph);
/// \brief Minimum Cost Arborescence algorithm class.
/// This class provides an efficient implementation of
/// Minimum Cost Arborescence algorithm. The arborescence is a tree
/// which is directed from a given source node of the digraph. One or
/// more sources should be given for the algorithm and it will calculate
/// the minimum cost subgraph which are union of arborescences with the
/// given sources and spans all the nodes which are reachable from the
/// sources. The time complexity of the algorithm is O(n<sup>2</sup>+e).
/// The algorithm provides also an optimal dual solution, therefore
/// the optimality of the solution can be checked.
/// \param GR The digraph type the algorithm runs on. The default value
/// \param CM This read-only ArcMap determines the costs of the
/// arcs. It is read once for each arc, so the map may involve in
/// relatively time consuming process to compute the arc cost if
/// it is necessary. The default map type is \ref
/// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
/// \param TR Traits class to set various data types used
/// by the algorithm. The default traits class is
/// \ref MinCostArborescenceDefaultTraits
/// "MinCostArborescenceDefaultTraits<GR, CM>". See \ref
/// MinCostArborescenceDefaultTraits for the documentation of a
/// MinCostArborescence traits class.
template <typename GR = ListDigraph,
typename CM = typename GR::template ArcMap<int>,
MinCostArborescenceDefaultTraits<GR, CM> >
template <typename GR, typename CM, typedef TR>
class MinCostArborescence {
/// The type of the underlying digraph.
typedef typename Traits::Digraph Digraph;
/// The type of the map that stores the arc costs.
typedef typename Traits::CostMap CostMap;
///The type of the costs of the arcs.
typedef typename Traits::Value Value;
///The type of the predecessor map.
typedef typename Traits::PredMap PredMap;
///The type of the map that stores which arcs are in the arborescence.
typedef typename Traits::ArborescenceMap ArborescenceMap;
typedef MinCostArborescence Create;
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
CostArc(Arc _arc, Value _value) : arc(_arc), value(_value) {}
ArborescenceMap *_arborescence;
typedef typename Digraph::template ArcMap<int> ArcOrder;
typedef typename Digraph::template NodeMap<int> NodeOrder;
typedef typename Digraph::template NodeMap<CostArc> CostArcMap;
std::vector<CostArc> arcs;
std::vector<StackLevel> level_stack;
typedef std::vector<typename Digraph::Node> DualNodeList;
DualNodeList _dual_node_list;
DualVariable(int _begin, int _end, Value _value)
: begin(_begin), end(_end), value(_value) {}
typedef std::vector<DualVariable> DualVariables;
DualVariables _dual_variables;
typedef typename Digraph::template NodeMap<int> HeapCrossRef;
HeapCrossRef *_heap_cross_ref;
typedef BinHeap<int, HeapCrossRef> Heap;
void createStructures() {
_pred = Traits::createPredMap(*_digraph);
local_arborescence = true;
_arborescence = Traits::createArborescenceMap(*_digraph);
_arc_order = new ArcOrder(*_digraph);
_node_order = new NodeOrder(*_digraph);
_cost_arcs = new CostArcMap(*_digraph);
_heap_cross_ref = new HeapCrossRef(*_digraph, -1);
_heap = new Heap(*_heap_cross_ref);
void destroyStructures() {
if (local_arborescence) {
(*_node_order)[node] = _dual_node_list.size();
level.node_level = _dual_node_list.size();
_dual_node_list.push_back(node);
for (InArcIt it(*_digraph, node); it != INVALID; ++it) {
Node source = _digraph->source(arc);
Value value = (*_cost)[it];
if (source == node || (*_node_order)[source] == -3) continue;
if ((*_cost_arcs)[source].arc == INVALID) {
(*_cost_arcs)[source].arc = arc;
(*_cost_arcs)[source].value = value;
if ((*_cost_arcs)[source].value > value) {
(*_cost_arcs)[source].arc = arc;
(*_cost_arcs)[source].value = value;
CostArc minimum = (*_cost_arcs)[nodes[0]];
for (int i = 1; i < int(nodes.size()); ++i) {
if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
minimum = (*_cost_arcs)[nodes[i]];
(*_arc_order)[minimum.arc] = _dual_variables.size();
DualVariable var(_dual_node_list.size() - 1,
_dual_node_list.size(), minimum.value);
_dual_variables.push_back(var);
for (int i = 0; i < int(nodes.size()); ++i) {
(*_cost_arcs)[nodes[i]].value -= minimum.value;
level.arcs.push_back((*_cost_arcs)[nodes[i]]);
(*_cost_arcs)[nodes[i]].arc = INVALID;
level_stack.push_back(level);
Arc contract(Node node) {
int node_bottom = bottom(node);
while (!level_stack.empty() &&
level_stack.back().node_level >= node_bottom) {
for (int i = 0; i < int(level_stack.back().arcs.size()); ++i) {
Arc arc = level_stack.back().arcs[i].arc;
Node source = _digraph->source(arc);
Value value = level_stack.back().arcs[i].value;
if ((*_node_order)[source] >= node_bottom) continue;
if ((*_cost_arcs)[source].arc == INVALID) {
(*_cost_arcs)[source].arc = arc;
(*_cost_arcs)[source].value = value;
if ((*_cost_arcs)[source].value > value) {
(*_cost_arcs)[source].arc = arc;
(*_cost_arcs)[source].value = value;
CostArc minimum = (*_cost_arcs)[nodes[0]];
for (int i = 1; i < int(nodes.size()); ++i) {
if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
minimum = (*_cost_arcs)[nodes[i]];
(*_arc_order)[minimum.arc] = _dual_variables.size();
DualVariable var(node_bottom, _dual_node_list.size(), minimum.value);
_dual_variables.push_back(var);
level.node_level = node_bottom;
for (int i = 0; i < int(nodes.size()); ++i) {
(*_cost_arcs)[nodes[i]].value -= minimum.value;
level.arcs.push_back((*_cost_arcs)[nodes[i]]);
(*_cost_arcs)[nodes[i]].arc = INVALID;
level_stack.push_back(level);
int k = level_stack.size() - 1;
while (level_stack[k].node_level > (*_node_order)[node]) {
return level_stack[k].node_level;
Node node = _digraph->target(arc);
_heap->push(node, (*_arc_order)[arc]);
while (!_heap->empty()) {
Node source = _heap->top();
(*_node_order)[source] = -1;
for (OutArcIt it(*_digraph, source); it != INVALID; ++it) {
if ((*_arc_order)[it] < 0) continue;
Node target = _digraph->target(it);
switch(_heap->state(target)) {
_heap->push(target, (*_arc_order)[it]);
if ((*_arc_order)[it] < (*_heap)[target]) {
_heap->decrease(target, (*_arc_order)[it]);
_arborescence->set((*_pred)[source], true);
/// \name Named Template Parameters
struct DefArborescenceMapTraits : public Traits {
typedef T ArborescenceMap;
static ArborescenceMap *createArborescenceMap(const Digraph &)
LEMON_ASSERT(false, "ArborescenceMap is not initialized");
return 0; // ignore warnings
/// \brief \ref named-templ-param "Named parameter" for
/// setting ArborescenceMap type
/// \ref named-templ-param "Named parameter" for setting
struct DefArborescenceMap
: public MinCostArborescence<Digraph, CostMap,
DefArborescenceMapTraits<T> > {
struct DefPredMapTraits : public Traits {
static PredMap *createPredMap(const Digraph &)
LEMON_ASSERT(false, "PredMap is not initialized");
/// \brief \ref named-templ-param "Named parameter" for
/// \ref named-templ-param "Named parameter" for setting
: public MinCostArborescence<Digraph, CostMap, DefPredMapTraits<T> > {
/// \param digraph The digraph the algorithm will run on.
/// \param cost The cost map used by the algorithm.
MinCostArborescence(const Digraph& digraph, const CostMap& cost)
: _digraph(&digraph), _cost(&cost), _pred(0), local_pred(false),
_arborescence(0), local_arborescence(false),
_arc_order(0), _node_order(0), _cost_arcs(0),
_heap_cross_ref(0), _heap(0) {}
/// \brief Sets the arborescence map.
/// Sets the arborescence map.
/// \return <tt>(*this)</tt>
MinCostArborescence& arborescenceMap(ArborescenceMap& m) {
if (local_arborescence) {
local_arborescence = false;
/// \brief Sets the arborescence map.
/// Sets the arborescence map.
/// \return <tt>(*this)</tt>
MinCostArborescence& predMap(PredMap& m) {
/// \name Query Functions
/// The result of the %MinCostArborescence algorithm can be obtained
/// using these functions.\n
/// Before the use of these functions,
/// either run() or start() must be called.
/// \brief Returns a reference to the arborescence map.
/// Returns a reference to the arborescence map.
const ArborescenceMap& arborescenceMap() const {
/// \brief Returns true if the arc is in the arborescence.
/// Returns true if the arc is in the arborescence.
/// \param arc The arc of the digraph.
/// \pre \ref run() must be called before using this function.
bool arborescence(Arc arc) const {
return (*_pred)[_digraph->target(arc)] == arc;
/// \brief Returns a reference to the pred map.
/// Returns a reference to the pred map.
const PredMap& predMap() const {
/// \brief Returns the predecessor arc of the given node.
/// Returns the predecessor arc of the given node.
Arc pred(Node node) const {
/// \brief Returns the cost of the arborescence.
/// Returns the cost of the arborescence.
Value arborescenceValue() const {
for (ArcIt it(*_digraph); it != INVALID; ++it) {
/// \brief Indicates that a node is reachable from the sources.
/// Indicates that a node is reachable from the sources.
bool reached(Node node) const {
return (*_node_order)[node] != -3;
/// \brief Indicates that a node is processed.
/// Indicates that a node is processed. The arborescence path exists
/// from the source to the given node.
bool processed(Node node) const {
return (*_node_order)[node] == -1;
/// \brief Returns the number of the dual variables in basis.
/// Returns the number of the dual variables in basis.
return _dual_variables.size();
/// \brief Returns the value of the dual solution.
/// Returns the value of the dual solution. It should be
/// equal to the arborescence value.
Value dualValue() const {
for (int i = 0; i < int(_dual_variables.size()); ++i) {
sum += _dual_variables[i].value;
/// \brief Returns the number of the nodes in the dual variable.
/// Returns the number of the nodes in the dual variable.
int dualSize(int k) const {
return _dual_variables[k].end - _dual_variables[k].begin;
/// \brief Returns the value of the dual variable.
/// Returns the the value of the dual variable.
const Value& dualValue(int k) const {
return _dual_variables[k].value;
/// \brief Lemon iterator for get a dual variable.
/// Lemon iterator for get a dual variable. This class provides
/// a common style lemon iterator which gives back a subset of
/// Constructor for get the nodeset of the variable.
DualIt(const MinCostArborescence& algorithm, int variable)
_index = _algorithm->_dual_variables[variable].begin;
_last = _algorithm->_dual_variables[variable].end;
/// \brief Conversion to node.
return _algorithm->_dual_node_list[_index];
/// \brief Increment operator.
/// \brief Validity checking
/// Checks whether the iterator is invalid.
bool operator==(Invalid) const {
/// \brief Validity checking
/// Checks whether the iterator is valid.
bool operator!=(Invalid) const {
const MinCostArborescence* _algorithm;
/// \name Execution Control
/// The simplest way to execute the algorithm is to use
/// one of the member functions called \c run(...). \n
/// If you need more control on the execution,
/// first you must call \ref init(), then you can add several
/// source nodes with \ref addSource().
/// Finally \ref start() will perform the arborescence
/// \brief Initializes the internal data structures.
/// Initializes the internal data structures.
for (NodeIt it(*_digraph); it != INVALID; ++it) {
(*_cost_arcs)[it].arc = INVALID;
(*_heap_cross_ref)[it] = Heap::PRE_HEAP;
for (ArcIt it(*_digraph); it != INVALID; ++it) {
_arborescence->set(it, false);
/// \brief Adds a new source node.
/// Adds a new source node to the algorithm.
void addSource(Node source) {
Node node = nodes.back();
for (OutArcIt it(*_digraph, node); it != INVALID; ++it) {
Node target = _digraph->target(it);
if ((*_node_order)[target] == -3) {
(*_node_order)[target] = -2;
(*_node_order)[source] = -1;
/// \brief Processes the next node in the priority queue.
/// Processes the next node in the priority queue.
/// \return The processed node.
/// \warning The queue must not be empty!
Node node = queue.back();
if ((*_node_order)[node] == -2) {
Node source = _digraph->source(arc);
while ((*_node_order)[source] != -1) {
if ((*_node_order)[source] >= 0) {
source = _digraph->source(arc);
/// \brief Returns the number of the nodes to be processed.
/// Returns the number of the nodes to be processed.
/// \brief Returns \c false if there are nodes to be processed.
/// Returns \c false if there are nodes to be processed.
bool emptyQueue() const {
/// \brief Executes the algorithm.
/// Executes the algorithm.
/// \pre init() must be called and at least one node should be added
/// with addSource() before using this function.
///\note mca.start() is just a shortcut of the following code.
///while (!mca.emptyQueue()) {
/// mca.processNextNode();
/// \brief Runs %MinCostArborescence algorithm from node \c s.
/// This method runs the %MinCostArborescence algorithm from
/// \note mca.run(s) is just a shortcut of the following code.
/// \brief Function type interface for MinCostArborescence algorithm.
/// Function type interface for MinCostArborescence algorithm.
/// \param digraph The Digraph that the algorithm runs on.
/// \param cost The CostMap of the arcs.
/// \param source The source of the arborescence.
/// \retval arborescence The bool ArcMap which stores the arborescence.
/// \return The cost of the arborescence.
/// \sa MinCostArborescence
template <typename Digraph, typename CostMap, typename ArborescenceMap>
typename CostMap::Value minCostArborescence(const Digraph& digraph,
typename Digraph::Node source,
ArborescenceMap& arborescence) {
typename MinCostArborescence<Digraph, CostMap>
::template DefArborescenceMap<ArborescenceMap>
::Create mca(digraph, cost);
mca.arborescenceMap(arborescence);
return mca.arborescenceValue();