154 #ifndef UTIL_GRAPH_GRAPH_H_
155 #define UTIL_GRAPH_GRAPH_H_
165 #include <type_traits>
168 #include "absl/base/port.h"
169 #include "absl/debugging/leak_check.h"
170 #include "absl/types/span.h"
171 #include "ortools/base/integral_types.h"
172 #include "ortools/base/logging.h"
173 #include "ortools/base/macros.h"
179 template <
typename T>
188 template <
typename NodeIndexType = int32_t,
typename ArcIndexType = int32_t,
189 bool HasReverseArcs =
false>
271 template <
typename A,
typename B>
273 LOG(FATAL) <<
"Not supported";
281 std::vector<ArcIndexType>* start,
282 std::vector<ArcIndexType>* permutation);
305 template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
330 void AddNode(NodeIndexType node);
338 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
349 void Build(std::vector<ArcIndexType>* permutation);
352 class OutgoingArcIterator;
353 class OutgoingHeadIterator;
360 ArcIndexType
OutDegree(NodeIndexType node)
const;
370 NodeIndexType node, ArcIndexType from)
const;
378 NodeIndexType
Tail(ArcIndexType arc)
const;
379 NodeIndexType
Head(ArcIndexType arc)
const;
385 std::vector<ArcIndexType> start_;
386 std::vector<ArcIndexType> next_;
387 std::vector<NodeIndexType> head_;
388 std::vector<NodeIndexType> tail_;
404 template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
415 StaticGraph() : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {}
417 : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {
424 template <
class ArcContainer>
426 const ArcContainer& arcs);
431 NodeIndexType
Head(ArcIndexType arc)
const;
432 NodeIndexType
Tail(ArcIndexType arc)
const;
433 ArcIndexType
OutDegree(NodeIndexType node)
const;
436 NodeIndexType node, ArcIndexType from)
const;
441 absl::Span<const NodeIndexType>
operator[](NodeIndexType node)
const;
445 void AddNode(NodeIndexType node);
446 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
449 void Build(std::vector<ArcIndexType>* permutation);
452 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
455 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
460 NodeIndexType last_tail_seen_;
461 std::vector<ArcIndexType> start_;
462 std::vector<NodeIndexType> head_;
463 std::vector<NodeIndexType> tail_;
472 template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
474 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
496 class OutgoingOrOppositeIncomingArcIterator;
497 class OppositeIncomingArcIterator;
498 class IncomingArcIterator;
499 class OutgoingArcIterator;
500 class OutgoingHeadIterator;
503 ArcIndexType
OutDegree(NodeIndexType node)
const;
504 ArcIndexType
InDegree(NodeIndexType node)
const;
517 NodeIndexType node)
const;
519 NodeIndexType node, ArcIndexType from)
const;
521 NodeIndexType node, ArcIndexType from)
const;
524 ArcIndexType from)
const;
526 NodeIndexType node, ArcIndexType from)
const;
533 NodeIndexType
Head(ArcIndexType arc)
const;
534 NodeIndexType
Tail(ArcIndexType arc)
const;
538 void AddNode(NodeIndexType node);
539 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
542 void Build(std::vector<ArcIndexType>* permutation);
545 std::vector<ArcIndexType> start_;
546 std::vector<ArcIndexType> reverse_start_;
560 template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
562 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
581 class OutgoingOrOppositeIncomingArcIterator;
582 class OppositeIncomingArcIterator;
583 class IncomingArcIterator;
584 class OutgoingArcIterator;
587 ArcIndexType
OutDegree(NodeIndexType node)
const;
588 ArcIndexType
InDegree(NodeIndexType node)
const;
595 NodeIndexType node)
const;
597 NodeIndexType node, ArcIndexType from)
const;
599 NodeIndexType node, ArcIndexType from)
const;
602 ArcIndexType from)
const;
604 NodeIndexType node, ArcIndexType from)
const;
609 absl::Span<const NodeIndexType>
operator[](NodeIndexType node)
const;
613 NodeIndexType
Head(ArcIndexType arc)
const;
614 NodeIndexType
Tail(ArcIndexType arc)
const;
617 void AddNode(NodeIndexType node);
618 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
621 void Build(std::vector<ArcIndexType>* permutation);
624 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
627 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
629 ArcIndexType ReverseArcLimit(NodeIndexType node)
const {
632 return node + 1 < num_nodes_ ? reverse_start_[node + 1] : 0;
636 std::vector<ArcIndexType> start_;
637 std::vector<ArcIndexType> reverse_start_;
638 SVector<NodeIndexType> head_;
639 SVector<ArcIndexType> opposite_;
648 template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
650 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
669 class OutgoingOrOppositeIncomingArcIterator;
670 class OppositeIncomingArcIterator;
671 class IncomingArcIterator;
672 class OutgoingArcIterator;
674 ArcIndexType
OutDegree(NodeIndexType node)
const;
675 ArcIndexType
InDegree(NodeIndexType node)
const;
682 NodeIndexType node)
const;
684 NodeIndexType node, ArcIndexType from)
const;
686 NodeIndexType node, ArcIndexType from)
const;
689 ArcIndexType from)
const;
691 NodeIndexType node, ArcIndexType from)
const;
696 absl::Span<const NodeIndexType>
operator[](NodeIndexType node)
const;
700 NodeIndexType
Head(ArcIndexType arc)
const;
701 NodeIndexType
Tail(ArcIndexType arc)
const;
704 void AddNode(NodeIndexType node);
705 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
708 void Build(std::vector<ArcIndexType>* permutation);
711 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
714 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
718 std::vector<ArcIndexType> start_;
719 std::vector<ArcIndexType> reverse_start_;
720 std::vector<ArcIndexType> next_;
721 SVector<NodeIndexType> head_;
737 template <
class IntVector,
class Array,
class ElementType>
739 Array* array_to_permute,
740 ElementType unused) {
741 std::vector<ElementType> temp(permutation.size());
742 for (
size_t i = 0; i < permutation.size(); ++i) {
743 temp[i] = (*array_to_permute)[i];
745 for (
size_t i = 0; i < permutation.size(); ++i) {
746 (*array_to_permute)[permutation[i]] = temp[i];
750 template <
class IntVector,
class Array>
751 void Permute(
const IntVector& permutation, Array* array_to_permute) {
752 if (permutation.empty()) {
756 (*array_to_permute)[0]);
761 template <
class IntVector>
763 std::vector<bool>* array_to_permute) {
764 if (permutation.empty()) {
785 template <
typename T>
788 SVector() : base_(nullptr), size_(0), capacity_(0) {}
795 if (capacity_ < other.size_) {
799 capacity_ = other.size_;
800 base_ = Allocate(capacity_);
801 CHECK(base_ !=
nullptr);
808 CopyInternal(other, std::is_integral<T>());
825 DCHECK_GE(n, -size_);
831 DCHECK_GE(n, -size_);
837 for (
int i = -n; i < -size_; ++i) {
840 for (
int i = size_; i < n; ++i) {
843 for (
int i = -size_; i < -n; ++i) {
846 for (
int i = n; i < size_; ++i) {
854 T*
data()
const {
return base_; }
857 std::swap(base_, x.base_);
858 std::swap(size_, x.size_);
859 std::swap(capacity_, x.capacity_);
866 const int new_capacity = std::min(n,
max_size());
867 T* new_storage = Allocate(new_capacity);
868 CHECK(new_storage !=
nullptr);
869 T* new_base = new_storage + new_capacity;
872 for (
int i = -size_; i < size_; ++i) {
873 new (new_base + i) T(std::move(base_[i]));
875 int saved_size = size_;
879 capacity_ = new_capacity;
885 void grow(
const T& left = T(),
const T& right = T()) {
886 if (size_ == capacity_) {
892 new (base_ + size_) T(right_copy);
893 new (base_ - size_ - 1) T(left_copy);
896 new (base_ + size_) T(right);
897 new (base_ - size_ - 1) T(left);
902 int size()
const {
return size_; }
906 int max_size()
const {
return std::numeric_limits<int>::max(); }
909 if (base_ ==
nullptr)
return;
912 free(base_ - capacity_);
922 void CopyInternal(
const SVector& other, std::true_type) {
923 std::memcpy(base_ - other.size_, other.base_ - other.size_,
924 2LL * other.size_ *
sizeof(T));
929 void CopyInternal(
const SVector& other, std::false_type) {
930 for (
int i = -size_; i < size_; ++i) {
931 new (base_ + i) T(other.base_[i]);
936 return absl::IgnoreLeak(
937 static_cast<T*
>(malloc(2LL *
capacity *
sizeof(T))));
940 int NewCapacity(
int delta) {
942 double candidate = 1.3 *
static_cast<double>(capacity_);
943 if (candidate >
static_cast<double>(
max_size())) {
944 candidate =
static_cast<double>(
max_size());
946 int new_capacity =
static_cast<int>(candidate);
947 if (new_capacity > capacity_ + delta) {
950 return capacity_ + delta;
960 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
961 IntegerRange<NodeIndexType>
966 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
972 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
975 std::numeric_limits<NodeIndexType>::max();
977 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
980 std::numeric_limits<ArcIndexType>::max();
982 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
987 return node_capacity_ > num_nodes_ ? node_capacity_ : num_nodes_;
990 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
994 return arc_capacity_ > num_arcs_ ? arc_capacity_ : num_arcs_;
997 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
998 void BaseGraph<NodeIndexType, ArcIndexType,
999 HasReverseArcs>::FreezeCapacities() {
1002 const_capacities_ =
true;
1003 node_capacity_ = std::max(node_capacity_, num_nodes_);
1004 arc_capacity_ = std::max(arc_capacity_, num_arcs_);
1009 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
1012 ArcIndexType sum = 0;
1013 for (
int i = 0; i < num_nodes_; ++i) {
1014 ArcIndexType temp = (*v)[i];
1018 DCHECK(sum == num_arcs_);
1026 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
1029 std::vector<ArcIndexType>* start,
1030 std::vector<ArcIndexType>* permutation) {
1034 start->assign(num_nodes_, 0);
1035 int last_tail_seen = 0;
1036 bool permutation_needed =
false;
1037 for (
int i = 0; i < num_arcs_; ++i) {
1038 NodeIndexType tail = (*head)[i];
1039 if (!permutation_needed) {
1040 permutation_needed = tail < last_tail_seen;
1041 last_tail_seen = tail;
1045 ComputeCumulativeSum(start);
1049 if (!permutation_needed) {
1050 for (
int i = 0; i < num_arcs_; ++i) {
1051 (*head)[i] = (*head)[~i];
1053 if (permutation !=
nullptr) {
1054 permutation->clear();
1061 std::vector<ArcIndexType> perm(num_arcs_);
1062 for (
int i = 0; i < num_arcs_; ++i) {
1063 perm[i] = (*start)[(*head)[i]]++;
1067 for (
int i = num_nodes_ - 1; i > 0; --i) {
1068 (*start)[i] = (*start)[i - 1];
1074 for (
int i = 0; i < num_arcs_; ++i) {
1075 (*head)[perm[i]] = (*head)[~i];
1077 if (permutation !=
nullptr) {
1078 permutation->swap(perm);
1091 #define DEFINE_RANGE_BASED_ARC_ITERATION(c, t, e) \
1092 template <typename NodeIndexType, typename ArcIndexType> \
1093 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1094 c<NodeIndexType, ArcIndexType>::t##Arcs(NodeIndexType node) const { \
1095 return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node), \
1096 t##ArcIterator(*this, node, e)); \
1098 template <typename NodeIndexType, typename ArcIndexType> \
1099 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1100 c<NodeIndexType, ArcIndexType>::t##ArcsStartingFrom( \
1101 NodeIndexType node, ArcIndexType from) const { \
1102 return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node, from), \
1103 t##ArcIterator(*this, node, e)); \
1108 #define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name) \
1109 using iterator_category = std::input_iterator_tag; \
1110 using difference_type = ptrdiff_t; \
1111 using pointer = const ArcIndexType*; \
1112 using value_type = ArcIndexType; \
1113 using reference = value_type; \
1114 bool operator!=(const iterator_class_name& other) const { \
1115 return this->index_ != other.index_; \
1117 bool operator==(const iterator_class_name& other) const { \
1118 return this->index_ == other.index_; \
1120 ArcIndexType operator*() const { return this->Index(); } \
1121 void operator++() { this->Next(); }
1127 template <
typename NodeIndexType,
typename ArcIndexType>
1136 template <
typename NodeIndexType,
typename ArcIndexType>
1138 ArcIndexType arc)
const {
1139 DCHECK(IsArcValid(arc));
1143 template <
typename NodeIndexType,
typename ArcIndexType>
1145 ArcIndexType arc)
const {
1146 DCHECK(IsArcValid(arc));
1150 template <
typename NodeIndexType,
typename ArcIndexType>
1152 NodeIndexType node)
const {
1153 ArcIndexType degree(0);
1154 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1158 template <
typename NodeIndexType,
typename ArcIndexType>
1160 if (node < num_nodes_)
return;
1161 DCHECK(!const_capacities_ || node < node_capacity_);
1162 num_nodes_ = node + 1;
1163 start_.resize(num_nodes_, Base::kNilArc);
1166 template <
typename NodeIndexType,
typename ArcIndexType>
1168 NodeIndexType tail, NodeIndexType head) {
1171 AddNode(tail > head ? tail : head);
1172 head_.push_back(head);
1173 tail_.push_back(tail);
1174 next_.push_back(start_[tail]);
1175 start_[tail] = num_arcs_;
1176 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1180 template <
typename NodeIndexType,
typename ArcIndexType>
1182 Base::ReserveNodes(bound);
1183 if (bound <= num_nodes_)
return;
1184 start_.reserve(bound);
1187 template <
typename NodeIndexType,
typename ArcIndexType>
1189 Base::ReserveArcs(bound);
1190 if (bound <= num_arcs_)
return;
1191 head_.reserve(bound);
1192 tail_.reserve(bound);
1193 next_.reserve(bound);
1196 template <
typename NodeIndexType,
typename ArcIndexType>
1198 std::vector<ArcIndexType>* permutation) {
1199 if (permutation !=
nullptr) {
1200 permutation->clear();
1204 template <
typename NodeIndexType,
typename ArcIndexType>
1208 : graph_(graph), index_(graph.start_[node]) {
1213 : graph_(graph), index_(arc) {
1218 ArcIndexType
Index()
const {
return index_; }
1221 index_ = graph_.next_[index_];
1228 ArcIndexType index_;
1231 template <
typename NodeIndexType,
typename ArcIndexType>
1241 : graph_(graph), index_(graph.start_[node]) {
1246 : graph_(graph), index_(arc) {
1251 NodeIndexType
Index()
const {
return graph_.Head(index_); }
1254 index_ = graph_.next_[index_];
1260 return index_ != other.index_;
1267 ArcIndexType index_;
1272 template <
typename NodeIndexType,
typename ArcIndexType>
1273 template <
class ArcContainer>
1276 const ArcContainer& arcs) {
1278 for (
const auto& [from, to] : arcs) g.
AddArc(from, to);
1285 template <
typename NodeIndexType,
typename ArcIndexType>
1286 absl::Span<const NodeIndexType>
1288 return absl::Span<const NodeIndexType>(head_.data() + start_[node],
1289 DirectArcLimit(node) - start_[node]);
1292 template <
typename NodeIndexType,
typename ArcIndexType>
1294 NodeIndexType node)
const {
1295 return DirectArcLimit(node) - start_[node];
1298 template <
typename NodeIndexType,
typename ArcIndexType>
1300 NodeIndexType bound) {
1301 Base::ReserveNodes(bound);
1302 if (bound <= num_nodes_)
return;
1303 start_.reserve(bound);
1306 template <
typename NodeIndexType,
typename ArcIndexType>
1308 Base::ReserveArcs(bound);
1309 if (bound <= num_arcs_)
return;
1310 head_.reserve(bound);
1311 tail_.reserve(bound);
1314 template <
typename NodeIndexType,
typename ArcIndexType>
1316 if (node < num_nodes_)
return;
1317 DCHECK(!const_capacities_ || node < node_capacity_) << node;
1318 num_nodes_ = node + 1;
1319 start_.resize(num_nodes_, 0);
1322 template <
typename NodeIndexType,
typename ArcIndexType>
1324 NodeIndexType tail, NodeIndexType head) {
1328 AddNode(tail > head ? tail : head);
1329 if (arc_in_order_) {
1330 if (tail >= last_tail_seen_) {
1332 last_tail_seen_ = tail;
1334 arc_in_order_ =
false;
1337 tail_.push_back(tail);
1338 head_.push_back(head);
1339 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1343 template <
typename NodeIndexType,
typename ArcIndexType>
1345 ArcIndexType arc)
const {
1346 DCHECK(IsArcValid(arc));
1350 template <
typename NodeIndexType,
typename ArcIndexType>
1352 ArcIndexType arc)
const {
1353 DCHECK(IsArcValid(arc));
1369 template <
typename NodeIndexType,
typename ArcIndexType>
1371 std::vector<ArcIndexType>* permutation) {
1373 if (is_built_)
return;
1375 node_capacity_ = num_nodes_;
1376 arc_capacity_ = num_arcs_;
1377 this->FreezeCapacities();
1380 if (arc_in_order_) {
1381 if (permutation !=
nullptr) {
1382 permutation->clear();
1384 this->ComputeCumulativeSum(&start_);
1390 start_.assign(num_nodes_, 0);
1391 for (
int i = 0; i < num_arcs_; ++i) {
1394 this->ComputeCumulativeSum(&start_);
1398 std::vector<ArcIndexType> perm(num_arcs_);
1399 for (
int i = 0; i < num_arcs_; ++i) {
1400 perm[i] = start_[tail_[i]]++;
1404 CHECK_EQ(tail_.size(),
static_cast<size_t>(num_arcs_));
1406 for (
int i = 0; i < num_arcs_; ++i) {
1407 head_[perm[i]] = tail_[i];
1410 if (permutation !=
nullptr) {
1411 permutation->swap(perm);
1415 for (
int i = num_nodes_ - 1; i > 0; --i) {
1416 start_[i] = start_[i - 1];
1421 for (
const NodeIndexType node : Base::AllNodes()) {
1422 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1428 template <
typename NodeIndexType,
typename ArcIndexType>
1432 : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
1435 : index_(arc), limit_(graph.DirectArcLimit(node)) {
1436 DCHECK_GE(arc, graph.start_[node]);
1439 bool Ok()
const {
return index_ < limit_; }
1440 ArcIndexType
Index()
const {
return index_; }
1456 ArcIndexType index_;
1457 const ArcIndexType limit_;
1465 OutgoingOrOppositeIncoming, Base::kNilArc);
1469 template <
typename NodeIndexType,
typename ArcIndexType>
1471 NodeIndexType, ArcIndexType>::OutgoingHeadIterator>
1473 NodeIndexType node)
const {
1479 template <
typename NodeIndexType,
typename ArcIndexType>
1481 NodeIndexType node)
const {
1482 ArcIndexType degree(0);
1483 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1487 template <
typename NodeIndexType,
typename ArcIndexType>
1489 NodeIndexType node)
const {
1490 ArcIndexType degree(0);
1491 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1495 template <
typename NodeIndexType,
typename ArcIndexType>
1497 ArcIndexType arc)
const {
1498 DCHECK(IsArcValid(arc));
1502 template <
typename NodeIndexType,
typename ArcIndexType>
1504 ArcIndexType arc)
const {
1505 DCHECK(IsArcValid(arc));
1509 template <
typename NodeIndexType,
typename ArcIndexType>
1511 ArcIndexType arc)
const {
1512 return head_[OppositeArc(arc)];
1515 template <
typename NodeIndexType,
typename ArcIndexType>
1517 NodeIndexType bound) {
1518 Base::ReserveNodes(bound);
1519 if (bound <= num_nodes_)
return;
1520 start_.reserve(bound);
1521 reverse_start_.reserve(bound);
1524 template <
typename NodeIndexType,
typename ArcIndexType>
1526 ArcIndexType bound) {
1527 Base::ReserveArcs(bound);
1528 if (bound <= num_arcs_)
return;
1529 head_.reserve(bound);
1530 next_.reserve(bound);
1533 template <
typename NodeIndexType,
typename ArcIndexType>
1535 NodeIndexType node) {
1536 if (node < num_nodes_)
return;
1537 DCHECK(!const_capacities_ || node < node_capacity_);
1538 num_nodes_ = node + 1;
1539 start_.resize(num_nodes_, Base::kNilArc);
1540 reverse_start_.resize(num_nodes_, Base::kNilArc);
1543 template <
typename NodeIndexType,
typename ArcIndexType>
1545 NodeIndexType tail, NodeIndexType head) {
1548 AddNode(tail > head ? tail : head);
1549 head_.grow(tail, head);
1550 next_.grow(reverse_start_[head], start_[tail]);
1551 start_[tail] = num_arcs_;
1552 reverse_start_[head] = ~num_arcs_;
1553 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1557 template <
typename NodeIndexType,
typename ArcIndexType>
1559 std::vector<ArcIndexType>* permutation) {
1560 if (permutation !=
nullptr) {
1561 permutation->clear();
1565 template <
typename NodeIndexType,
typename ArcIndexType>
1569 : graph_(graph), index_(graph.start_[node]) {
1574 : graph_(graph), index_(arc) {
1580 ArcIndexType
Index()
const {
return index_; }
1583 index_ = graph_.next_[index_];
1590 ArcIndexType index_;
1593 template <
typename NodeIndexType,
typename ArcIndexType>
1599 : graph_(graph), index_(graph.reverse_start_[node]) {
1603 NodeIndexType node, ArcIndexType arc)
1604 : graph_(graph), index_(arc) {
1611 ArcIndexType
Index()
const {
return index_; }
1614 index_ = graph_.next_[index_];
1624 template <
typename NodeIndexType,
typename ArcIndexType>
1640 : this->graph_.OppositeArc(this->index_);
1646 template <
typename NodeIndexType,
typename ArcIndexType>
1652 : graph_(graph), index_(graph.reverse_start_[node]), node_(node) {
1657 NodeIndexType node, ArcIndexType arc)
1658 : graph_(graph), index_(arc), node_(node) {
1664 ArcIndexType
Index()
const {
return index_; }
1668 index_ = graph_.next_[index_];
1670 index_ = graph_.start_[node_];
1673 index_ = graph_.next_[index_];
1681 ArcIndexType index_;
1682 const NodeIndexType node_;
1685 template <
typename NodeIndexType,
typename ArcIndexType>
1689 : graph_(&graph), index_(graph.start_[node]) {
1694 : graph_(&graph), index_(arc) {
1700 ArcIndexType
Index()
const {
return graph_->Head(index_); }
1703 index_ = graph_->next_[index_];
1710 ArcIndexType index_;
1716 DirectArcLimit(node));
1718 ReverseArcLimit(node));
1720 OutgoingOrOppositeIncoming,
1721 DirectArcLimit(node));
1723 ReverseArcLimit(node));
1725 template <
typename NodeIndexType,
typename ArcIndexType>
1727 NodeIndexType node)
const {
1728 return DirectArcLimit(node) - start_[node];
1731 template <
typename NodeIndexType,
typename ArcIndexType>
1733 NodeIndexType node)
const {
1734 return ReverseArcLimit(node) - reverse_start_[node];
1737 template <
typename NodeIndexType,
typename ArcIndexType>
1738 absl::Span<const NodeIndexType>
1740 NodeIndexType node)
const {
1741 return absl::Span<const NodeIndexType>(head_.data() + start_[node],
1742 DirectArcLimit(node) - start_[node]);
1745 template <
typename NodeIndexType,
typename ArcIndexType>
1747 ArcIndexType arc)
const {
1749 DCHECK(IsArcValid(arc));
1750 return opposite_[arc];
1753 template <
typename NodeIndexType,
typename ArcIndexType>
1755 ArcIndexType arc)
const {
1757 DCHECK(IsArcValid(arc));
1761 template <
typename NodeIndexType,
typename ArcIndexType>
1763 ArcIndexType arc)
const {
1765 return head_[OppositeArc(arc)];
1768 template <
typename NodeIndexType,
typename ArcIndexType>
1770 ArcIndexType bound) {
1771 Base::ReserveArcs(bound);
1772 if (bound <= num_arcs_)
return;
1773 head_.reserve(bound);
1776 template <
typename NodeIndexType,
typename ArcIndexType>
1778 NodeIndexType node) {
1779 if (node < num_nodes_)
return;
1780 DCHECK(!const_capacities_ || node < node_capacity_);
1781 num_nodes_ = node + 1;
1784 template <
typename NodeIndexType,
typename ArcIndexType>
1786 NodeIndexType tail, NodeIndexType head) {
1789 AddNode(tail > head ? tail : head);
1793 head_.grow(head, tail);
1794 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1798 template <
typename NodeIndexType,
typename ArcIndexType>
1800 std::vector<ArcIndexType>* permutation) {
1802 if (is_built_)
return;
1804 node_capacity_ = num_nodes_;
1805 arc_capacity_ = num_arcs_;
1806 this->FreezeCapacities();
1807 this->BuildStartAndForwardHead(&head_, &start_, permutation);
1810 reverse_start_.assign(num_nodes_, 0);
1811 for (
int i = 0; i < num_arcs_; ++i) {
1812 reverse_start_[head_[i]]++;
1814 this->ComputeCumulativeSum(&reverse_start_);
1818 opposite_.reserve(num_arcs_);
1819 for (
int i = 0; i < num_arcs_; ++i) {
1821 opposite_.grow(0, reverse_start_[head_[i]]++ - num_arcs_);
1825 for (
int i = num_nodes_ - 1; i > 0; --i) {
1826 reverse_start_[i] = reverse_start_[i - 1] - num_arcs_;
1828 if (num_nodes_ != 0) {
1829 reverse_start_[0] = -num_arcs_;
1833 for (
int i = 0; i < num_arcs_; ++i) {
1834 opposite_[opposite_[i]] = i;
1836 for (
const NodeIndexType node : Base::AllNodes()) {
1837 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1838 head_[opposite_[arc]] = node;
1843 template <
typename NodeIndexType,
typename ArcIndexType>
1847 : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
1850 : index_(arc), limit_(graph.DirectArcLimit(node)) {
1851 DCHECK_GE(arc, graph.start_[node]);
1854 bool Ok()
const {
return index_ < limit_; }
1855 ArcIndexType
Index()
const {
return index_; }
1866 ArcIndexType index_;
1867 const ArcIndexType limit_;
1870 template <
typename NodeIndexType,
typename ArcIndexType>
1877 limit_(graph.ReverseArcLimit(node)),
1878 index_(graph.reverse_start_[node]) {
1880 DCHECK_LE(index_, limit_);
1883 NodeIndexType node, ArcIndexType arc)
1884 : graph_(graph), limit_(graph.ReverseArcLimit(node)), index_(arc) {
1886 DCHECK_GE(index_, graph.reverse_start_[node]);
1887 DCHECK_LE(index_, limit_);
1890 bool Ok()
const {
return index_ < limit_; }
1891 ArcIndexType
Index()
const {
return index_; }
1905 template <
typename NodeIndexType,
typename ArcIndexType>
1914 arc == graph.ReverseArcLimit(node)
1915 ? graph.ReverseArcLimit(node)
1919 return this->index_ == this->limit_
1921 : this->graph_.OppositeArc(this->index_);
1927 template <
typename NodeIndexType,
typename ArcIndexType>
1933 : index_(graph.reverse_start_[node]),
1934 first_limit_(graph.ReverseArcLimit(node)),
1935 next_start_(graph.start_[node]),
1936 limit_(graph.DirectArcLimit(node)) {
1937 if (index_ == first_limit_) index_ = next_start_;
1939 DCHECK((index_ < first_limit_) || (index_ >= next_start_));
1942 NodeIndexType node, ArcIndexType arc)
1944 first_limit_(graph.ReverseArcLimit(node)),
1945 next_start_(graph.start_[node]),
1946 limit_(graph.DirectArcLimit(node)) {
1948 DCHECK((index_ >= graph.reverse_start_[node] && index_ < first_limit_) ||
1949 (index_ >= next_start_));
1952 ArcIndexType
Index()
const {
return index_; }
1953 bool Ok()
const {
return index_ < limit_; }
1957 if (index_ == first_limit_) {
1958 index_ = next_start_;
1965 ArcIndexType index_;
1966 const ArcIndexType first_limit_;
1967 const ArcIndexType next_start_;
1968 const ArcIndexType limit_;
1974 DirectArcLimit(node));
1977 OutgoingOrOppositeIncoming,
1978 DirectArcLimit(node));
1982 template <
typename NodeIndexType,
typename ArcIndexType>
1984 NodeIndexType node)
const {
1985 return DirectArcLimit(node) - start_[node];
1988 template <
typename NodeIndexType,
typename ArcIndexType>
1990 NodeIndexType node)
const {
1991 ArcIndexType degree(0);
1992 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1996 template <
typename NodeIndexType,
typename ArcIndexType>
1997 absl::Span<const NodeIndexType>
1999 NodeIndexType node)
const {
2000 return absl::Span<const NodeIndexType>(head_.data() + start_[node],
2001 DirectArcLimit(node) - start_[node]);
2004 template <
typename NodeIndexType,
typename ArcIndexType>
2006 ArcIndexType arc)
const {
2007 DCHECK(IsArcValid(arc));
2011 template <
typename NodeIndexType,
typename ArcIndexType>
2013 ArcIndexType arc)
const {
2015 DCHECK(IsArcValid(arc));
2019 template <
typename NodeIndexType,
typename ArcIndexType>
2021 ArcIndexType arc)
const {
2023 return head_[OppositeArc(arc)];
2026 template <
typename NodeIndexType,
typename ArcIndexType>
2028 ArcIndexType bound) {
2029 Base::ReserveArcs(bound);
2030 if (bound <= num_arcs_)
return;
2031 head_.reserve(bound);
2034 template <
typename NodeIndexType,
typename ArcIndexType>
2036 NodeIndexType node) {
2037 if (node < num_nodes_)
return;
2038 DCHECK(!const_capacities_ || node < node_capacity_);
2039 num_nodes_ = node + 1;
2042 template <
typename NodeIndexType,
typename ArcIndexType>
2044 NodeIndexType tail, NodeIndexType head) {
2047 AddNode(tail > head ? tail : head);
2051 head_.grow(head, tail);
2052 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
2056 template <
typename NodeIndexType,
typename ArcIndexType>
2058 std::vector<ArcIndexType>* permutation) {
2060 if (is_built_)
return;
2062 node_capacity_ = num_nodes_;
2063 arc_capacity_ = num_arcs_;
2064 this->FreezeCapacities();
2065 this->BuildStartAndForwardHead(&head_, &start_, permutation);
2068 for (
const NodeIndexType node : Base::AllNodes()) {
2069 for (
const ArcIndexType arc : OutgoingArcs(node)) {
2075 reverse_start_.assign(num_nodes_, Base::kNilArc);
2076 next_.reserve(num_arcs_);
2077 for (
const ArcIndexType arc : Base::AllForwardArcs()) {
2078 next_.push_back(reverse_start_[Head(arc)]);
2079 reverse_start_[Head(arc)] = -next_.size();
2083 template <
typename NodeIndexType,
typename ArcIndexType>
2087 : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
2090 : index_(arc), limit_(graph.DirectArcLimit(node)) {
2091 DCHECK_GE(arc, graph.start_[node]);
2094 bool Ok()
const {
return index_ < limit_; }
2095 ArcIndexType
Index()
const {
return index_; }
2106 ArcIndexType index_;
2107 const ArcIndexType limit_;
2110 template <
typename NodeIndexType,
typename ArcIndexType>
2117 DCHECK(graph.is_built_);
2119 index_ = graph.reverse_start_[node];
2122 NodeIndexType node, ArcIndexType arc)
2123 : graph_(&graph), index_(arc) {
2124 DCHECK(graph.is_built_);
2130 ArcIndexType
Index()
const {
return index_; }
2133 index_ = graph_->next_[~index_];
2143 template <
typename NodeIndexType,
typename ArcIndexType>
2156 : this->graph_->OppositeArc(this->index_);
2162 template <
typename NodeIndexType,
typename ArcIndexType>
2169 limit_ = graph.DirectArcLimit(node);
2170 index_ = graph.reverse_start_[node];
2171 restart_ = graph.start_[node];
2177 NodeIndexType node, ArcIndexType arc)
2179 limit_ = graph.DirectArcLimit(node);
2181 restart_ = graph.start_[node];
2186 return index_ < limit_;
2188 ArcIndexType
Index()
const {
return index_; }
2192 index_ = graph_->next_[graph_->OppositeArc(index_)];
2205 ArcIndexType index_;
2206 ArcIndexType restart_;
2207 ArcIndexType limit_;
2213 template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
2231 NodeIndexType
Head(ArcIndexType arc)
const;
2232 NodeIndexType
Tail(ArcIndexType arc)
const;
2233 ArcIndexType
OutDegree(NodeIndexType node)
const;
2236 ArcIndexType from)
const;
2240 template <
typename NodeIndexType,
typename ArcIndexType>
2242 ArcIndexType arc)
const {
2243 DCHECK(this->IsArcValid(arc));
2244 return arc % num_nodes_;
2247 template <
typename NodeIndexType,
typename ArcIndexType>
2249 ArcIndexType arc)
const {
2250 DCHECK(this->IsArcValid(arc));
2251 return arc / num_nodes_;
2254 template <
typename NodeIndexType,
typename ArcIndexType>
2256 NodeIndexType node)
const {
2260 template <
typename NodeIndexType,
typename ArcIndexType>
2263 NodeIndexType node)
const {
2264 DCHECK_LT(node, num_nodes_);
2266 static_cast<ArcIndexType
>(num_nodes_) * node,
2267 static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
2270 template <
typename NodeIndexType,
typename ArcIndexType>
2273 NodeIndexType node, ArcIndexType from)
const {
2274 DCHECK_LT(node, num_nodes_);
2276 from,
static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
2279 template <
typename NodeIndexType,
typename ArcIndexType>
2282 NodeIndexType node)
const {
2283 DCHECK_LT(node, num_nodes_);
2290 template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
2292 :
public BaseGraph<NodeIndexType, ArcIndexType, false> {
2306 : left_nodes_(left_nodes), right_nodes_(right_nodes) {
2307 this->
Reserve(left_nodes + right_nodes, left_nodes * right_nodes);
2309 num_nodes_ = left_nodes + right_nodes;
2310 num_arcs_ = left_nodes * right_nodes;
2313 NodeIndexType
Head(ArcIndexType arc)
const;
2314 NodeIndexType
Tail(ArcIndexType arc)
const;
2315 ArcIndexType
OutDegree(NodeIndexType node)
const;
2318 ArcIndexType from)
const;
2325 : index_(graph.right_nodes_ * node),
2326 limit_(node >= graph.left_nodes_ ? index_
2327 : graph.right_nodes_ * (node + 1)) {}
2329 bool Ok()
const {
return index_ < limit_; }
2330 ArcIndexType
Index()
const {
return index_; }
2334 ArcIndexType index_;
2335 const ArcIndexType limit_;
2339 const NodeIndexType left_nodes_;
2340 const NodeIndexType right_nodes_;
2343 template <
typename NodeIndexType,
typename ArcIndexType>
2345 ArcIndexType arc)
const {
2346 DCHECK(this->IsArcValid(arc));
2347 return left_nodes_ + arc % right_nodes_;
2350 template <
typename NodeIndexType,
typename ArcIndexType>
2352 ArcIndexType arc)
const {
2353 DCHECK(this->IsArcValid(arc));
2354 return arc / right_nodes_;
2357 template <
typename NodeIndexType,
typename ArcIndexType>
2359 NodeIndexType node)
const {
2360 return (node < left_nodes_) ? right_nodes_ : 0;
2363 template <
typename NodeIndexType,
typename ArcIndexType>
2366 NodeIndexType node)
const {
2367 if (node < left_nodes_) {
2369 right_nodes_ * (node + 1));
2375 template <
typename NodeIndexType,
typename ArcIndexType>
2378 NodeIndexType node, ArcIndexType from)
const {
2379 if (node < left_nodes_) {
2386 template <
typename NodeIndexType,
typename ArcIndexType>
2389 NodeIndexType node)
const {
2390 if (node < left_nodes_) {
2402 #undef DEFINE_RANGE_BASED_ARC_ITERATION
2403 #undef DEFINE_STL_ITERATOR_FUNCTIONS
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
NodeIndexType size() 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
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void AddNode(NodeIndexType node)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
ArcIndexType OutDegree(NodeIndexType node) 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< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
void ReserveArcs(ArcIndexType bound) override
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
void ReserveNodes(NodeIndexType bound) override
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcIndexType InDegree(NodeIndexType node) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void AddNode(NodeIndexType node)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
ReverseArcListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(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< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
void ReserveArcs(ArcIndexType bound) override
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcIndexType InDegree(NodeIndexType node) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void AddNode(NodeIndexType node)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
ReverseArcMixedGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
absl::Span< const NodeIndexType > operator[](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< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
ReverseArcStaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
void ReserveArcs(ArcIndexType bound) override
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcIndexType InDegree(NodeIndexType node) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void AddNode(NodeIndexType node)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
absl::Span< const NodeIndexType > operator[](NodeIndexType node) const
SVector(const SVector &other)
const T & operator[](int n) const
SVector & operator=(const SVector &other)
SVector & operator=(SVector &&other)
void grow(const T &left=T(), const T &right=T())
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
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void AddNode(NodeIndexType node)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
StaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
ArcIndexType OutDegree(NodeIndexType node) const
static StaticGraph FromArcs(NodeIndexType num_nodes, const ArcContainer &arcs)
NodeIndexType Head(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
absl::Span< const NodeIndexType > operator[](NodeIndexType node) const
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)