14#ifndef OR_TOOLS_GRAPH_MINIMUM_SPANNING_TREE_H_
15#define OR_TOOLS_GRAPH_MINIMUM_SPANNING_TREE_H_
20#include "absl/types/span.h"
47template <
typename Graph>
48std::vector<typename Graph::ArcIndex>
51 absl::Span<const typename Graph::ArcIndex> sorted_arcs) {
54 const int num_arcs = graph.
num_arcs();
56 std::vector<ArcIndex> tree_arcs;
60 const int expected_tree_size = graph.
num_nodes() - 1;
61 tree_arcs.reserve(expected_tree_size);
64 while (tree_arcs.size() != expected_tree_size && arc_index < num_arcs) {
65 const ArcIndex arc = sorted_arcs[arc_index];
66 const auto tail = graph.
Tail(arc);
67 const auto head = graph.
Head(arc);
70 tree_arcs.push_back(arc);
87template <
typename Graph,
typename ArcComparator>
89 const Graph& graph,
const ArcComparator& arc_comparator) {
91 std::vector<ArcIndex> sorted_arcs(graph.
num_arcs());
93 sorted_arcs[arc] = arc;
95 std::sort(sorted_arcs.begin(), sorted_arcs.end(), arc_comparator);
113template <
typename Graph,
typename ArcValue>
115 const Graph& graph,
const ArcValue& arc_value) {
118 using ArcValueType =
decltype(arc_value(0));
119 std::vector<ArcIndex> tree_arcs;
123 const int expected_tree_size = graph.
num_nodes() - 1;
124 tree_arcs.reserve(expected_tree_size);
126 std::vector<bool> node_active(graph.
num_nodes(),
true);
133 void SetHeapIndex(
int index) { heap_index = index; }
134 int GetHeapIndex()
const {
return heap_index; }
135 bool operator<(
const Entry& other)
const {
return value > other.value; }
143 std::vector<Entry> entries;
144 std::vector<bool> touched_entry(graph.
num_nodes(),
false);
146 entries.push_back({node, std::numeric_limits<ArcValueType>::max(), -1});
148 entries[0].value = 0;
150 while (!pq.
IsEmpty() && tree_arcs.size() != expected_tree_size) {
151 const Entry* best = pq.
Top();
154 node_active[node] =
false;
156 tree_arcs.push_back(node_neighbor[node]);
160 if (node_active[neighbor]) {
161 const ArcValueType value = arc_value(arc);
162 Entry& entry = entries[neighbor];
163 if (value < entry.value || !touched_entry[neighbor]) {
164 node_neighbor[neighbor] = arc;
166 touched_entry[neighbor] =
true;
bool Contains(const T *val) const
void Pop()
If there are ties for the top, this returns all of them.
void NoteChangedPriority(T *val)
A connected components finder that only works on dense ints.
bool Connected(int node1, int node2)
bool AddEdge(int node1, int node2)
void SetNumberOfNodes(int num_nodes)
NodeIndexType num_nodes() const
IntegerRange< ArcIndex > AllForwardArcs() const
ArcIndexType num_arcs() const
Returns the number of valid arcs in the graph.
IntegerRange< NodeIndex > AllNodes() const
BaseGraph implementation -------------------------------------------------—.
static const int32_t kNilArc
NodeIndexType Tail(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
In SWIG mode, we don't want anything besides these top-level includes.
std::vector< typename Graph::ArcIndex > BuildPrimMinimumSpanningTree(const Graph &graph, const ArcValue &arc_value)
std::vector< typename Graph::ArcIndex > BuildKruskalMinimumSpanningTreeFromSortedArcs(const Graph &graph, absl::Span< const typename Graph::ArcIndex > sorted_arcs)
util::ReverseArcStaticGraph Graph
Type of graph to use.
std::vector< typename Graph::ArcIndex > BuildKruskalMinimumSpanningTree(const Graph &graph, const ArcComparator &arc_comparator)