155#ifndef UTIL_GRAPH_GRAPH_H_
156#define UTIL_GRAPH_GRAPH_H_
166#include "absl/debugging/leak_check.h"
184template <
typename NodeIndexType = int32_t,
typename ArcIndexType = int32_t,
185 bool HasReverseArcs =
false>
265 template <
typename A,
typename B>
275 std::vector<ArcIndexType>* start,
276 std::vector<ArcIndexType>* permutation);
298template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
323 void AddNode(NodeIndexType node);
342 void Build(std::vector<ArcIndexType>* permutation);
345 class OutgoingArcIterator;
346 class OutgoingHeadIterator;
353 ArcIndexType
OutDegree(NodeIndexType node)
const;
363 NodeIndexType node, ArcIndexType from)
const;
371 NodeIndexType
Tail(ArcIndexType arc)
const;
372 NodeIndexType
Head(ArcIndexType arc)
const;
378 std::vector<ArcIndexType> start_;
379 std::vector<ArcIndexType> next_;
380 std::vector<NodeIndexType> head_;
381 std::vector<NodeIndexType> tail_;
397template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
408 StaticGraph() : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {}
410 : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {
417 class OutgoingArcIterator;
419 NodeIndexType
Head(ArcIndexType arc)
const;
420 NodeIndexType
Tail(ArcIndexType arc)
const;
421 ArcIndexType
OutDegree(NodeIndexType node)
const;
424 NodeIndexType node, ArcIndexType from)
const;
433 void AddNode(NodeIndexType node);
437 void Build(std::vector<ArcIndexType>* permutation);
440 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
443 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
448 NodeIndexType last_tail_seen_;
449 std::vector<ArcIndexType> start_;
450 std::vector<NodeIndexType> head_;
451 std::vector<NodeIndexType> tail_;
460template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
462 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
484 class OutgoingOrOppositeIncomingArcIterator;
485 class OppositeIncomingArcIterator;
486 class IncomingArcIterator;
487 class OutgoingArcIterator;
488 class OutgoingHeadIterator;
491 ArcIndexType
OutDegree(NodeIndexType node)
const;
492 ArcIndexType
InDegree(NodeIndexType node)
const;
505 NodeIndexType node)
const;
507 NodeIndexType node, ArcIndexType from)
const;
509 NodeIndexType node, ArcIndexType from)
const;
512 ArcIndexType from)
const;
514 NodeIndexType node, ArcIndexType from)
const;
521 NodeIndexType
Head(ArcIndexType arc)
const;
522 NodeIndexType
Tail(ArcIndexType arc)
const;
526 void AddNode(NodeIndexType node);
530 void Build(std::vector<ArcIndexType>* permutation);
533 std::vector<ArcIndexType> start_;
534 std::vector<ArcIndexType> reverse_start_;
548template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
550 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
569 class OutgoingOrOppositeIncomingArcIterator;
570 class OppositeIncomingArcIterator;
571 class IncomingArcIterator;
572 class OutgoingArcIterator;
575 ArcIndexType
OutDegree(NodeIndexType node)
const;
576 ArcIndexType
InDegree(NodeIndexType node)
const;
583 NodeIndexType node)
const;
585 NodeIndexType node, ArcIndexType from)
const;
587 NodeIndexType node, ArcIndexType from)
const;
590 ArcIndexType from)
const;
592 NodeIndexType node, ArcIndexType from)
const;
601 NodeIndexType
Head(ArcIndexType arc)
const;
602 NodeIndexType
Tail(ArcIndexType arc)
const;
605 void AddNode(NodeIndexType node);
609 void Build(std::vector<ArcIndexType>* permutation);
612 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
615 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
617 ArcIndexType ReverseArcLimit(NodeIndexType node)
const {
620 return node + 1 < num_nodes_ ? reverse_start_[node + 1] : 0;
624 std::vector<ArcIndexType> start_;
625 std::vector<ArcIndexType> reverse_start_;
626 SVector<NodeIndexType> head_;
627 SVector<ArcIndexType> opposite_;
636template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
638 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
657 class OutgoingOrOppositeIncomingArcIterator;
658 class OppositeIncomingArcIterator;
659 class IncomingArcIterator;
660 class OutgoingArcIterator;
662 ArcIndexType
OutDegree(NodeIndexType node)
const;
663 ArcIndexType
InDegree(NodeIndexType node)
const;
670 NodeIndexType node)
const;
672 NodeIndexType node, ArcIndexType from)
const;
674 NodeIndexType node, ArcIndexType from)
const;
677 ArcIndexType from)
const;
679 NodeIndexType node, ArcIndexType from)
const;
688 NodeIndexType
Head(ArcIndexType arc)
const;
689 NodeIndexType
Tail(ArcIndexType arc)
const;
692 void AddNode(NodeIndexType node);
696 void Build(std::vector<ArcIndexType>* permutation);
699 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
702 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
706 std::vector<ArcIndexType> start_;
707 std::vector<ArcIndexType> reverse_start_;
708 std::vector<ArcIndexType> next_;
709 SVector<NodeIndexType> head_;
725template <
class IntVector,
class Array,
class ElementType>
727 Array* array_to_permute,
728 ElementType unused) {
729 std::vector<ElementType> temp(permutation.size());
730 for (
int i = 0; i < permutation.size(); ++i) {
731 temp[i] = (*array_to_permute)[i];
733 for (
int i = 0; i < permutation.size(); ++i) {
734 (*array_to_permute)[permutation[i]] = temp[i];
738template <
class IntVector,
class Array>
739void Permute(
const IntVector& permutation, Array* array_to_permute) {
740 if (permutation.empty()) {
744 (*array_to_permute)[0]);
749template <
class IntVector>
751 std::vector<bool>* array_to_permute) {
752 if (permutation.empty()) {
776 SVector() : base_(nullptr), size_(0), capacity_(0) {}
783 if (capacity_ < other.size_) {
787 capacity_ = other.size_;
788 base_ = Allocate(capacity_);
789 CHECK(base_ !=
nullptr);
796 for (
int i = -size_; i < size_; ++i) {
797 new (base_ + i) T(other.base_[i]);
827 for (
int i = -n; i < -size_; ++i) {
830 for (
int i = size_; i < n; ++i) {
833 for (
int i = -size_; i < -n; ++i) {
836 for (
int i = n; i < size_; ++i) {
844 T*
data()
const {
return base_; }
857 T* new_storage = Allocate(new_capacity);
858 CHECK(new_storage !=
nullptr);
859 T* new_base = new_storage + new_capacity;
862 for (
int i = -size_; i < size_; ++i) {
863 new (new_base + i) T(std::move(base_[i]));
865 int saved_size = size_;
869 capacity_ = new_capacity;
875 void grow(
const T& left = T(),
const T& right = T()) {
876 if (size_ == capacity_) {
882 new (base_ + size_) T(right_copy);
883 new (base_ - size_ - 1) T(left_copy);
886 new (base_ + size_) T(right);
887 new (base_ - size_ - 1) T(left);
892 int size()
const {
return size_; }
899 if (base_ ==
nullptr)
return;
902 free(base_ - capacity_);
910 return absl::IgnoreLeak(
914 int NewCapacity(
int delta) {
916 double candidate = 1.3 *
static_cast<double>(capacity_);
917 if (candidate >
static_cast<double>(
max_size())) {
918 candidate =
static_cast<double>(
max_size());
920 int new_capacity =
static_cast<int>(candidate);
921 if (new_capacity > capacity_ +
delta) {
924 return capacity_ +
delta;
934template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
935IntegerRange<NodeIndexType>
940template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
946template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
951template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
956template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
961 return node_capacity_ > num_nodes_ ? node_capacity_ : num_nodes_;
964template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
968 return arc_capacity_ > num_arcs_ ? arc_capacity_ : num_arcs_;
971template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
972void BaseGraph<NodeIndexType, ArcIndexType,
973 HasReverseArcs>::FreezeCapacities() {
976 const_capacities_ =
true;
977 node_capacity_ =
std::max(node_capacity_, num_nodes_);
978 arc_capacity_ =
std::max(arc_capacity_, num_arcs_);
983template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
986 ArcIndexType sum = 0;
987 for (
int i = 0; i < num_nodes_; ++i) {
988 ArcIndexType temp = (*v)[i];
1000template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
1003 std::vector<ArcIndexType>* start,
1004 std::vector<ArcIndexType>* permutation) {
1008 start->assign(num_nodes_, 0);
1009 int last_tail_seen = 0;
1010 bool permutation_needed =
false;
1011 for (
int i = 0; i < num_arcs_; ++i) {
1012 NodeIndexType
tail = (*head)[i];
1013 if (!permutation_needed) {
1014 permutation_needed =
tail < last_tail_seen;
1015 last_tail_seen =
tail;
1019 ComputeCumulativeSum(start);
1023 if (!permutation_needed) {
1024 for (
int i = 0; i < num_arcs_; ++i) {
1025 (*head)[i] = (*head)[~i];
1027 if (permutation !=
nullptr) {
1028 permutation->clear();
1035 std::vector<ArcIndexType> perm(num_arcs_);
1036 for (
int i = 0; i < num_arcs_; ++i) {
1037 perm[i] = (*start)[(*head)[i]]++;
1041 for (
int i = num_nodes_ - 1; i > 0; --i) {
1042 (*start)[i] = (*start)[i - 1];
1048 for (
int i = 0; i < num_arcs_; ++i) {
1049 (*head)[perm[i]] = (*head)[~i];
1051 if (permutation !=
nullptr) {
1052 permutation->swap(perm);
1065#define DEFINE_RANGE_BASED_ARC_ITERATION(c, t, e) \
1066 template <typename NodeIndexType, typename ArcIndexType> \
1067 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1068 c<NodeIndexType, ArcIndexType>::t##Arcs(NodeIndexType node) const { \
1069 return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node), \
1070 t##ArcIterator(*this, node, e)); \
1072 template <typename NodeIndexType, typename ArcIndexType> \
1073 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1074 c<NodeIndexType, ArcIndexType>::t##ArcsStartingFrom( \
1075 NodeIndexType node, ArcIndexType from) const { \
1076 return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node, from), \
1077 t##ArcIterator(*this, node, e)); \
1082#define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name) \
1083 using iterator_category = std::input_iterator_tag; \
1084 using difference_type = ptrdiff_t; \
1085 using pointer = const ArcIndexType*; \
1086 using reference = const ArcIndexType&; \
1087 using value_type = ArcIndexType; \
1088 bool operator!=(const iterator_class_name& other) const { \
1089 return this->index_ != other.index_; \
1091 bool operator==(const iterator_class_name& other) const { \
1092 return this->index_ == other.index_; \
1094 ArcIndexType operator*() const { return this->Index(); } \
1095 void operator++() { this->Next(); }
1101template <
typename NodeIndexType,
typename ArcIndexType>
1110template <
typename NodeIndexType,
typename ArcIndexType>
1112 ArcIndexType arc)
const {
1117template <
typename NodeIndexType,
typename ArcIndexType>
1119 ArcIndexType arc)
const {
1124template <
typename NodeIndexType,
typename ArcIndexType>
1126 NodeIndexType node)
const {
1127 ArcIndexType degree(0);
1128 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1132template <
typename NodeIndexType,
typename ArcIndexType>
1134 if (node < num_nodes_)
return;
1135 DCHECK(!const_capacities_ || node < node_capacity_);
1136 num_nodes_ = node + 1;
1137 start_.resize(num_nodes_, Base::kNilArc);
1140template <
typename NodeIndexType,
typename ArcIndexType>
1142 NodeIndexType
tail, NodeIndexType
head) {
1146 head_.push_back(
head);
1147 tail_.push_back(
tail);
1148 next_.push_back(start_[
tail]);
1149 start_[
tail] = num_arcs_;
1150 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1154template <
typename NodeIndexType,
typename ArcIndexType>
1156 Base::ReserveNodes(
bound);
1157 if (
bound <= num_nodes_)
return;
1158 start_.reserve(
bound);
1161template <
typename NodeIndexType,
typename ArcIndexType>
1163 Base::ReserveArcs(
bound);
1164 if (
bound <= num_arcs_)
return;
1165 head_.reserve(
bound);
1166 tail_.reserve(
bound);
1167 next_.reserve(
bound);
1170template <
typename NodeIndexType,
typename ArcIndexType>
1172 std::vector<ArcIndexType>* permutation) {
1173 if (permutation !=
nullptr) {
1174 permutation->clear();
1178template <
typename NodeIndexType,
typename ArcIndexType>
1182 : graph_(graph), index_(graph.start_[node]) {
1187 : graph_(graph), index_(arc) {
1192 ArcIndexType
Index()
const {
return index_; }
1195 index_ = graph_.next_[index_];
1202 ArcIndexType index_;
1205template <
typename NodeIndexType,
typename ArcIndexType>
1215 : graph_(graph), index_(graph.start_[node]) {
1220 : graph_(graph), index_(arc) {
1225 NodeIndexType
Index()
const {
return graph_.Head(index_); }
1228 index_ = graph_.next_[index_];
1234 return index_ != other.index_;
1241 ArcIndexType index_;
1248template <
typename NodeIndexType,
typename ArcIndexType>
1252 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1255template <
typename NodeIndexType,
typename ArcIndexType>
1257 NodeIndexType node)
const {
1258 return DirectArcLimit(node) - start_[node];
1261template <
typename NodeIndexType,
typename ArcIndexType>
1263 NodeIndexType
bound) {
1264 Base::ReserveNodes(
bound);
1265 if (
bound <= num_nodes_)
return;
1266 start_.reserve(
bound);
1269template <
typename NodeIndexType,
typename ArcIndexType>
1271 Base::ReserveArcs(
bound);
1272 if (
bound <= num_arcs_)
return;
1273 head_.reserve(
bound);
1274 tail_.reserve(
bound);
1277template <
typename NodeIndexType,
typename ArcIndexType>
1279 if (node < num_nodes_)
return;
1280 DCHECK(!const_capacities_ || node < node_capacity_) << node;
1281 num_nodes_ = node + 1;
1282 start_.resize(num_nodes_, 0);
1285template <
typename NodeIndexType,
typename ArcIndexType>
1287 NodeIndexType
tail, NodeIndexType
head) {
1292 if (arc_in_order_) {
1293 if (
tail >= last_tail_seen_) {
1295 last_tail_seen_ =
tail;
1297 arc_in_order_ =
false;
1300 tail_.push_back(
tail);
1301 head_.push_back(
head);
1302 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1306template <
typename NodeIndexType,
typename ArcIndexType>
1308 ArcIndexType arc)
const {
1313template <
typename NodeIndexType,
typename ArcIndexType>
1315 ArcIndexType arc)
const {
1332template <
typename NodeIndexType,
typename ArcIndexType>
1334 std::vector<ArcIndexType>* permutation) {
1336 if (is_built_)
return;
1338 node_capacity_ = num_nodes_;
1339 arc_capacity_ = num_arcs_;
1340 this->FreezeCapacities();
1343 if (arc_in_order_) {
1344 if (permutation !=
nullptr) {
1345 permutation->clear();
1347 this->ComputeCumulativeSum(&start_);
1353 start_.assign(num_nodes_, 0);
1354 for (
int i = 0; i < num_arcs_; ++i) {
1357 this->ComputeCumulativeSum(&start_);
1361 std::vector<ArcIndexType> perm(num_arcs_);
1362 for (
int i = 0; i < num_arcs_; ++i) {
1363 perm[i] = start_[tail_[i]]++;
1369 for (
int i = 0; i < num_arcs_; ++i) {
1370 head_[perm[i]] = tail_[i];
1373 if (permutation !=
nullptr) {
1374 permutation->swap(perm);
1378 for (
int i = num_nodes_ - 1; i > 0; --i) {
1379 start_[i] = start_[i - 1];
1384 for (
const NodeIndexType node : Base::AllNodes()) {
1385 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1391template <
typename NodeIndexType,
typename ArcIndexType>
1395 : index_(graph.start_[node]),
limit_(graph.DirectArcLimit(node)) {}
1398 : index_(arc),
limit_(graph.DirectArcLimit(node)) {
1403 ArcIndexType
Index()
const {
return index_; }
1419 ArcIndexType index_;
1420 const ArcIndexType
limit_;
1428 OutgoingOrOppositeIncoming, Base::kNilArc);
1432template <
typename NodeIndexType,
typename ArcIndexType>
1434 NodeIndexType, ArcIndexType>::OutgoingHeadIterator>
1436 NodeIndexType node)
const {
1442template <
typename NodeIndexType,
typename ArcIndexType>
1444 NodeIndexType node)
const {
1445 ArcIndexType degree(0);
1446 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1450template <
typename NodeIndexType,
typename ArcIndexType>
1452 NodeIndexType node)
const {
1453 ArcIndexType degree(0);
1454 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1458template <
typename NodeIndexType,
typename ArcIndexType>
1460 ArcIndexType arc)
const {
1465template <
typename NodeIndexType,
typename ArcIndexType>
1467 ArcIndexType arc)
const {
1472template <
typename NodeIndexType,
typename ArcIndexType>
1474 ArcIndexType arc)
const {
1475 return head_[OppositeArc(arc)];
1478template <
typename NodeIndexType,
typename ArcIndexType>
1480 NodeIndexType
bound) {
1481 Base::ReserveNodes(
bound);
1482 if (
bound <= num_nodes_)
return;
1483 start_.reserve(
bound);
1484 reverse_start_.reserve(
bound);
1487template <
typename NodeIndexType,
typename ArcIndexType>
1489 ArcIndexType
bound) {
1490 Base::ReserveArcs(
bound);
1491 if (
bound <= num_arcs_)
return;
1492 head_.reserve(
bound);
1493 next_.reserve(
bound);
1496template <
typename NodeIndexType,
typename ArcIndexType>
1498 NodeIndexType node) {
1499 if (node < num_nodes_)
return;
1500 DCHECK(!const_capacities_ || node < node_capacity_);
1501 num_nodes_ = node + 1;
1502 start_.resize(num_nodes_, Base::kNilArc);
1503 reverse_start_.resize(num_nodes_, Base::kNilArc);
1506template <
typename NodeIndexType,
typename ArcIndexType>
1508 NodeIndexType
tail, NodeIndexType
head) {
1513 next_.grow(reverse_start_[
head], start_[
tail]);
1514 start_[
tail] = num_arcs_;
1515 reverse_start_[
head] = ~num_arcs_;
1516 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1520template <
typename NodeIndexType,
typename ArcIndexType>
1522 std::vector<ArcIndexType>* permutation) {
1523 if (permutation !=
nullptr) {
1524 permutation->clear();
1528template <
typename NodeIndexType,
typename ArcIndexType>
1532 : graph_(graph), index_(graph.start_[node]) {
1537 : graph_(graph), index_(arc) {
1543 ArcIndexType
Index()
const {
return index_; }
1546 index_ = graph_.next_[index_];
1553 ArcIndexType index_;
1556template <
typename NodeIndexType,
typename ArcIndexType>
1562 : graph_(graph), index_(graph.reverse_start_[node]) {
1566 NodeIndexType node, ArcIndexType arc)
1567 : graph_(graph), index_(arc) {
1574 ArcIndexType
Index()
const {
return index_; }
1577 index_ = graph_.next_[index_];
1587template <
typename NodeIndexType,
typename ArcIndexType>
1603 : this->graph_.OppositeArc(this->index_);
1609template <
typename NodeIndexType,
typename ArcIndexType>
1615 : graph_(graph), index_(graph.reverse_start_[node]), node_(node) {
1620 NodeIndexType node, ArcIndexType arc)
1621 : graph_(graph), index_(arc), node_(node) {
1627 ArcIndexType
Index()
const {
return index_; }
1631 index_ = graph_.next_[index_];
1633 index_ = graph_.start_[node_];
1636 index_ = graph_.next_[index_];
1644 ArcIndexType index_;
1645 const NodeIndexType node_;
1648template <
typename NodeIndexType,
typename ArcIndexType>
1652 : graph_(&graph), index_(graph.start_[node]) {
1657 : graph_(&graph), index_(arc) {
1663 ArcIndexType
Index()
const {
return graph_->Head(index_); }
1666 index_ = graph_->next_[index_];
1673 ArcIndexType index_;
1679 DirectArcLimit(node));
1681 ReverseArcLimit(node));
1683 OutgoingOrOppositeIncoming,
1684 DirectArcLimit(node));
1686 ReverseArcLimit(node));
1688template <
typename NodeIndexType,
typename ArcIndexType>
1690 NodeIndexType node)
const {
1691 return DirectArcLimit(node) - start_[node];
1694template <
typename NodeIndexType,
typename ArcIndexType>
1696 NodeIndexType node)
const {
1697 return ReverseArcLimit(node) - reverse_start_[node];
1700template <
typename NodeIndexType,
typename ArcIndexType>
1703 NodeIndexType node)
const {
1705 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1708template <
typename NodeIndexType,
typename ArcIndexType>
1710 ArcIndexType arc)
const {
1713 return opposite_[arc];
1716template <
typename NodeIndexType,
typename ArcIndexType>
1718 ArcIndexType arc)
const {
1724template <
typename NodeIndexType,
typename ArcIndexType>
1726 ArcIndexType arc)
const {
1728 return head_[OppositeArc(arc)];
1731template <
typename NodeIndexType,
typename ArcIndexType>
1733 ArcIndexType
bound) {
1734 Base::ReserveArcs(
bound);
1735 if (
bound <= num_arcs_)
return;
1736 head_.reserve(
bound);
1739template <
typename NodeIndexType,
typename ArcIndexType>
1741 NodeIndexType node) {
1742 if (node < num_nodes_)
return;
1743 DCHECK(!const_capacities_ || node < node_capacity_);
1744 num_nodes_ = node + 1;
1747template <
typename NodeIndexType,
typename ArcIndexType>
1749 NodeIndexType
tail, NodeIndexType
head) {
1757 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1761template <
typename NodeIndexType,
typename ArcIndexType>
1763 std::vector<ArcIndexType>* permutation) {
1765 if (is_built_)
return;
1767 node_capacity_ = num_nodes_;
1768 arc_capacity_ = num_arcs_;
1769 this->FreezeCapacities();
1770 this->BuildStartAndForwardHead(&head_, &start_, permutation);
1773 reverse_start_.assign(num_nodes_, 0);
1774 for (
int i = 0; i < num_arcs_; ++i) {
1775 reverse_start_[head_[i]]++;
1777 this->ComputeCumulativeSum(&reverse_start_);
1781 opposite_.reserve(num_arcs_);
1782 for (
int i = 0; i < num_arcs_; ++i) {
1784 opposite_.grow(0, reverse_start_[head_[i]]++ - num_arcs_);
1788 for (
int i = num_nodes_ - 1; i > 0; --i) {
1789 reverse_start_[i] = reverse_start_[i - 1] - num_arcs_;
1791 if (num_nodes_ != 0) {
1792 reverse_start_[0] = -num_arcs_;
1796 for (
int i = 0; i < num_arcs_; ++i) {
1797 opposite_[opposite_[i]] = i;
1799 for (
const NodeIndexType node : Base::AllNodes()) {
1800 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1801 head_[opposite_[arc]] = node;
1806template <
typename NodeIndexType,
typename ArcIndexType>
1810 : index_(graph.start_[node]),
limit_(graph.DirectArcLimit(node)) {}
1813 : index_(arc),
limit_(graph.DirectArcLimit(node)) {
1818 ArcIndexType
Index()
const {
return index_; }
1829 ArcIndexType index_;
1830 const ArcIndexType
limit_;
1833template <
typename NodeIndexType,
typename ArcIndexType>
1840 limit_(graph.ReverseArcLimit(node)),
1841 index_(graph.reverse_start_[node]) {
1846 NodeIndexType node, ArcIndexType arc)
1847 : graph_(graph),
limit_(graph.ReverseArcLimit(node)), index_(arc) {
1849 DCHECK_GE(index_, graph.reverse_start_[node]);
1854 ArcIndexType
Index()
const {
return index_; }
1868template <
typename NodeIndexType,
typename ArcIndexType>
1877 arc == graph.ReverseArcLimit(node)
1878 ? graph.ReverseArcLimit(node)
1882 return this->index_ == this->
limit_
1884 : this->graph_.OppositeArc(this->index_);
1890template <
typename NodeIndexType,
typename ArcIndexType>
1896 : index_(graph.reverse_start_[node]),
1897 first_limit_(graph.ReverseArcLimit(node)),
1898 next_start_(graph.start_[node]),
1899 limit_(graph.DirectArcLimit(node)) {
1900 if (index_ == first_limit_) index_ = next_start_;
1902 DCHECK((index_ < first_limit_) || (index_ >= next_start_));
1905 NodeIndexType node, ArcIndexType arc)
1907 first_limit_(graph.ReverseArcLimit(node)),
1908 next_start_(graph.start_[node]),
1909 limit_(graph.DirectArcLimit(node)) {
1911 DCHECK((index_ >= graph.reverse_start_[node] && index_ < first_limit_) ||
1912 (index_ >= next_start_));
1915 ArcIndexType
Index()
const {
return index_; }
1920 if (index_ == first_limit_) {
1921 index_ = next_start_;
1928 ArcIndexType index_;
1929 const ArcIndexType first_limit_;
1930 const ArcIndexType next_start_;
1931 const ArcIndexType
limit_;
1937 DirectArcLimit(node));
1940 OutgoingOrOppositeIncoming,
1941 DirectArcLimit(node));
1945template <
typename NodeIndexType,
typename ArcIndexType>
1947 NodeIndexType node)
const {
1948 return DirectArcLimit(node) - start_[node];
1951template <
typename NodeIndexType,
typename ArcIndexType>
1953 NodeIndexType node)
const {
1954 ArcIndexType degree(0);
1955 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1959template <
typename NodeIndexType,
typename ArcIndexType>
1962 NodeIndexType node)
const {
1964 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1967template <
typename NodeIndexType,
typename ArcIndexType>
1969 ArcIndexType arc)
const {
1974template <
typename NodeIndexType,
typename ArcIndexType>
1976 ArcIndexType arc)
const {
1982template <
typename NodeIndexType,
typename ArcIndexType>
1984 ArcIndexType arc)
const {
1986 return head_[OppositeArc(arc)];
1989template <
typename NodeIndexType,
typename ArcIndexType>
1991 ArcIndexType
bound) {
1992 Base::ReserveArcs(
bound);
1993 if (
bound <= num_arcs_)
return;
1994 head_.reserve(
bound);
1997template <
typename NodeIndexType,
typename ArcIndexType>
1999 NodeIndexType node) {
2000 if (node < num_nodes_)
return;
2001 DCHECK(!const_capacities_ || node < node_capacity_);
2002 num_nodes_ = node + 1;
2005template <
typename NodeIndexType,
typename ArcIndexType>
2007 NodeIndexType
tail, NodeIndexType
head) {
2015 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
2019template <
typename NodeIndexType,
typename ArcIndexType>
2021 std::vector<ArcIndexType>* permutation) {
2023 if (is_built_)
return;
2025 node_capacity_ = num_nodes_;
2026 arc_capacity_ = num_arcs_;
2027 this->FreezeCapacities();
2028 this->BuildStartAndForwardHead(&head_, &start_, permutation);
2031 for (
const NodeIndexType node : Base::AllNodes()) {
2032 for (
const ArcIndexType arc : OutgoingArcs(node)) {
2038 reverse_start_.assign(num_nodes_, Base::kNilArc);
2039 next_.reserve(num_arcs_);
2040 for (
const ArcIndexType arc : Base::AllForwardArcs()) {
2041 next_.push_back(reverse_start_[Head(arc)]);
2042 reverse_start_[Head(arc)] = -next_.size();
2046template <
typename NodeIndexType,
typename ArcIndexType>
2050 : index_(graph.start_[node]),
limit_(graph.DirectArcLimit(node)) {}
2053 : index_(arc),
limit_(graph.DirectArcLimit(node)) {
2058 ArcIndexType
Index()
const {
return index_; }
2069 ArcIndexType index_;
2070 const ArcIndexType
limit_;
2073template <
typename NodeIndexType,
typename ArcIndexType>
2082 index_ = graph.reverse_start_[node];
2085 NodeIndexType node, ArcIndexType arc)
2086 : graph_(&graph), index_(arc) {
2093 ArcIndexType
Index()
const {
return index_; }
2096 index_ = graph_->next_[~index_];
2106template <
typename NodeIndexType,
typename ArcIndexType>
2119 : this->graph_->OppositeArc(this->index_);
2125template <
typename NodeIndexType,
typename ArcIndexType>
2132 limit_ = graph.DirectArcLimit(node);
2133 index_ = graph.reverse_start_[node];
2134 restart_ = graph.start_[node];
2140 NodeIndexType node, ArcIndexType arc)
2142 limit_ = graph.DirectArcLimit(node);
2144 restart_ = graph.start_[node];
2151 ArcIndexType
Index()
const {
return index_; }
2155 index_ = graph_->next_[graph_->OppositeArc(index_)];
2168 ArcIndexType index_;
2169 ArcIndexType restart_;
2176template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
2194 NodeIndexType
Head(ArcIndexType arc)
const;
2195 NodeIndexType
Tail(ArcIndexType arc)
const;
2196 ArcIndexType
OutDegree(NodeIndexType node)
const;
2199 ArcIndexType from)
const;
2203template <
typename NodeIndexType,
typename ArcIndexType>
2205 ArcIndexType arc)
const {
2206 DCHECK(this->IsArcValid(arc));
2207 return arc % num_nodes_;
2210template <
typename NodeIndexType,
typename ArcIndexType>
2212 ArcIndexType arc)
const {
2213 DCHECK(this->IsArcValid(arc));
2214 return arc / num_nodes_;
2217template <
typename NodeIndexType,
typename ArcIndexType>
2219 NodeIndexType node)
const {
2223template <
typename NodeIndexType,
typename ArcIndexType>
2226 NodeIndexType node)
const {
2229 static_cast<ArcIndexType
>(num_nodes_) * node,
2230 static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
2233template <
typename NodeIndexType,
typename ArcIndexType>
2236 NodeIndexType node, ArcIndexType from)
const {
2239 from,
static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
2242template <
typename NodeIndexType,
typename ArcIndexType>
2245 NodeIndexType node)
const {
2253template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
2255 :
public BaseGraph<NodeIndexType, ArcIndexType, false> {
2269 : left_nodes_(left_nodes), right_nodes_(right_nodes) {
2270 this->
Reserve(left_nodes + right_nodes, left_nodes * right_nodes);
2272 num_nodes_ = left_nodes + right_nodes;
2273 num_arcs_ = left_nodes * right_nodes;
2276 NodeIndexType
Head(ArcIndexType arc)
const;
2277 NodeIndexType
Tail(ArcIndexType arc)
const;
2278 ArcIndexType
OutDegree(NodeIndexType node)
const;
2281 ArcIndexType from)
const;
2288 : index_(graph.right_nodes_ * node),
2289 limit_(node >= graph.left_nodes_ ? index_
2290 : graph.right_nodes_ * (node + 1)) {}
2292 bool Ok()
const {
return index_ < limit_; }
2293 ArcIndexType
Index()
const {
return index_; }
2297 ArcIndexType index_;
2298 const ArcIndexType limit_;
2302 const NodeIndexType left_nodes_;
2303 const NodeIndexType right_nodes_;
2306template <
typename NodeIndexType,
typename ArcIndexType>
2308 ArcIndexType arc)
const {
2309 DCHECK(this->IsArcValid(arc));
2310 return left_nodes_ + arc % right_nodes_;
2313template <
typename NodeIndexType,
typename ArcIndexType>
2315 ArcIndexType arc)
const {
2316 DCHECK(this->IsArcValid(arc));
2317 return arc / right_nodes_;
2320template <
typename NodeIndexType,
typename ArcIndexType>
2322 NodeIndexType node)
const {
2323 return (node < left_nodes_) ? right_nodes_ : 0;
2326template <
typename NodeIndexType,
typename ArcIndexType>
2329 NodeIndexType node)
const {
2330 if (node < left_nodes_) {
2332 right_nodes_ * (node + 1));
2338template <
typename NodeIndexType,
typename ArcIndexType>
2341 NodeIndexType node, ArcIndexType from)
const {
2342 if (node < left_nodes_) {
2349template <
typename NodeIndexType,
typename ArcIndexType>
2352 NodeIndexType node)
const {
2353 if (node < left_nodes_) {
2365#undef DEFINE_RANGE_BASED_ARC_ITERATION
2366#undef DEFINE_STL_ITERATOR_FUNCTIONS
#define DCHECK_LE(val1, val2)
#define CHECK_EQ(val1, val2)
#define DCHECK_GE(val1, val2)
#define DCHECK_LT(val1, val2)
#define DCHECK(condition)
ArcIndexType arc_capacity_
static const NodeIndexType kNilNode
IntegerRange< ArcIndex > AllForwardArcs() const
void GroupForwardArcsByFunctor(const A &a, B *b)
bool IsNodeValid(NodeIndexType node) const
virtual void ReserveArcs(ArcIndexType bound)
void Reserve(NodeIndexType node_capacity, ArcIndexType arc_capacity)
NodeIndexType node_capacity_
ArcIndexType num_arcs() const
void BuildStartAndForwardHead(SVector< NodeIndexType > *head, std::vector< ArcIndexType > *start, std::vector< ArcIndexType > *permutation)
NodeIndexType num_nodes() const
ArcIndexType arc_capacity() const
IntegerRange< NodeIndex > AllNodes() const
static const ArcIndexType kNilArc
void ComputeCumulativeSum(std::vector< ArcIndexType > *v)
ArcIndexType max_end_arc_index() const
NodeIndexType node_capacity() const
bool IsArcValid(ArcIndexType arc) const
virtual void ReserveNodes(NodeIndexType bound)
OutgoingArcIterator(const CompleteBipartiteGraph &graph, NodeIndexType node)
ArcIndexType Index() const
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
ArcIndexType OutDegree(NodeIndexType node) const
CompleteBipartiteGraph(NodeIndexType left_nodes, NodeIndexType right_nodes)
IntegerRange< NodeIndexType > operator[](NodeIndexType node) const
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
CompleteGraph(NodeIndexType num_nodes)
ArcIndexType OutDegree(NodeIndexType node) const
IntegerRange< NodeIndexType > operator[](NodeIndexType node) const
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator)
OutgoingArcIterator(const ListGraph &graph, NodeIndexType node, ArcIndexType arc)
OutgoingArcIterator(const ListGraph &graph, NodeIndexType node)
ArcIndexType Index() const
const NodeIndexType * pointer
NodeIndexType Index() const
const NodeIndexType & reference
bool operator!=(const typename ListGraph< NodeIndexType, ArcIndexType >::OutgoingHeadIterator &other) const
NodeIndexType operator*() const
std::input_iterator_tag iterator_category
OutgoingHeadIterator(const ListGraph &graph, NodeIndexType node, ArcIndexType arc)
ptrdiff_t difference_type
OutgoingHeadIterator(const ListGraph &graph, NodeIndexType node)
BeginEndWrapper< OutgoingHeadIterator > operator[](NodeIndexType node) const
ListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
NodeIndexType Tail(ArcIndexType arc) const
void ReserveArcs(ArcIndexType bound) override
void ReserveNodes(NodeIndexType bound) override
void AddNode(NodeIndexType node)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
ArcIndexType OutDegree(NodeIndexType node) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
IncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node, ArcIndexType arc)
IncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
DEFINE_STL_ITERATOR_FUNCTIONS(IncomingArcIterator)
ArcIndexType Index() const
OppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node, ArcIndexType arc)
const ReverseArcListGraph & graph_
DEFINE_STL_ITERATOR_FUNCTIONS(OppositeIncomingArcIterator)
OppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
ArcIndexType Index() const
OutgoingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
OutgoingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node, ArcIndexType arc)
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator)
ArcIndexType Index() const
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingHeadIterator)
OutgoingHeadIterator(const ReverseArcListGraph &graph, NodeIndexType node)
ArcIndexType Index() const
OutgoingHeadIterator(const ReverseArcListGraph &graph, NodeIndexType node, ArcIndexType arc)
OutgoingOrOppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingOrOppositeIncomingArcIterator)
ArcIndexType Index() const
OutgoingOrOppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node, ArcIndexType arc)
ArcIndexType OppositeArc(ArcIndexType arc) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Tail(ArcIndexType arc) const
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
void ReserveArcs(ArcIndexType bound) override
void ReserveNodes(NodeIndexType bound) override
ArcIndexType InDegree(NodeIndexType node) const
void AddNode(NodeIndexType node)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
ReverseArcListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
ArcIndexType OutDegree(NodeIndexType node) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
BeginEndWrapper< OutgoingHeadIterator > operator[](NodeIndexType node) const
IncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
IncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node, ArcIndexType arc)
DEFINE_STL_ITERATOR_FUNCTIONS(IncomingArcIterator)
ArcIndexType Index() const
DEFINE_STL_ITERATOR_FUNCTIONS(OppositeIncomingArcIterator)
OppositeIncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node, ArcIndexType arc)
const ReverseArcMixedGraph * graph_
OppositeIncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
ArcIndexType Index() const
OutgoingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node, ArcIndexType arc)
OutgoingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator)
ArcIndexType Index() const
OutgoingOrOppositeIncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
OutgoingOrOppositeIncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node, ArcIndexType arc)
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingOrOppositeIncomingArcIterator)
ArcIndexType Index() const
ArcIndexType OppositeArc(ArcIndexType arc) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Tail(ArcIndexType arc) const
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
void ReserveArcs(ArcIndexType bound) override
ArcIndexType InDegree(NodeIndexType node) const
void AddNode(NodeIndexType node)
BeginEndWrapper< NodeIndexType const * > operator[](NodeIndexType node) const
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
ReverseArcMixedGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
IncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
IncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node, ArcIndexType arc)
DEFINE_STL_ITERATOR_FUNCTIONS(IncomingArcIterator)
ArcIndexType Index() const
OppositeIncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
const ReverseArcStaticGraph & graph_
OppositeIncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node, ArcIndexType arc)
DEFINE_STL_ITERATOR_FUNCTIONS(OppositeIncomingArcIterator)
const ArcIndexType limit_
ArcIndexType Index() const
OutgoingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node, ArcIndexType arc)
OutgoingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator)
ArcIndexType Index() const
OutgoingOrOppositeIncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingOrOppositeIncomingArcIterator)
OutgoingOrOppositeIncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node, ArcIndexType arc)
ArcIndexType Index() const
ArcIndexType OppositeArc(ArcIndexType arc) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Tail(ArcIndexType arc) const
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
ReverseArcStaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
void ReserveArcs(ArcIndexType bound) override
ArcIndexType InDegree(NodeIndexType node) const
void AddNode(NodeIndexType node)
BeginEndWrapper< NodeIndexType const * > operator[](NodeIndexType node) const
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
SVector(const SVector &other)
SVector & operator=(SVector &&other)
SVector & operator=(const SVector &other)
void grow(const T &left=T(), const T &right=T())
const T & operator[](int n) const
void swap(SVector< T > &x)
OutgoingArcIterator(const StaticGraph &graph, NodeIndexType node, ArcIndexType arc)
DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator)
OutgoingArcIterator(const StaticGraph &graph, NodeIndexType node)
ArcIndexType Index() const
NodeIndexType Tail(ArcIndexType arc) const
void ReserveArcs(ArcIndexType bound) override
void ReserveNodes(NodeIndexType bound) override
void AddNode(NodeIndexType node)
BeginEndWrapper< NodeIndexType const * > operator[](NodeIndexType node) const
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
StaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
ArcIndexType OutDegree(NodeIndexType node) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
void swap(IdMap< K, V > &a, IdMap< K, V > &b)
DEFINE_RANGE_BASED_ARC_ITERATION(ListGraph, Outgoing, Base::kNilArc)
void Permute(const IntVector &permutation, Array *array_to_permute)
void PermuteWithExplicitElementType(const IntVector &permutation, Array *array_to_permute, ElementType unused)