155#ifndef UTIL_GRAPH_GRAPH_H_
156#define UTIL_GRAPH_GRAPH_H_
166#include "absl/base/port.h"
167#include "absl/debugging/leak_check.h"
168#include "ortools/base/integral_types.h"
169#include "ortools/base/logging.h"
170#include "ortools/base/macros.h"
185template <
typename NodeIndexType = int32_t,
typename ArcIndexType = int32_t,
186 bool HasReverseArcs =
false>
266 template <
typename A,
typename B>
268 LOG(FATAL) <<
"Not supported";
276 std::vector<ArcIndexType>* start,
277 std::vector<ArcIndexType>* permutation);
299template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
324 void AddNode(NodeIndexType node);
332 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
343 void Build(std::vector<ArcIndexType>* permutation);
346 class OutgoingArcIterator;
347 class OutgoingHeadIterator;
354 ArcIndexType
OutDegree(NodeIndexType node)
const;
364 NodeIndexType node, ArcIndexType from)
const;
372 NodeIndexType
Tail(ArcIndexType arc)
const;
373 NodeIndexType
Head(ArcIndexType arc)
const;
379 std::vector<ArcIndexType> start_;
380 std::vector<ArcIndexType> next_;
381 std::vector<NodeIndexType> head_;
382 std::vector<NodeIndexType> tail_;
398template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
409 StaticGraph() : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {}
411 : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {
418 class OutgoingArcIterator;
420 NodeIndexType
Head(ArcIndexType arc)
const;
421 NodeIndexType
Tail(ArcIndexType arc)
const;
422 ArcIndexType
OutDegree(NodeIndexType node)
const;
425 NodeIndexType node, ArcIndexType from)
const;
434 void AddNode(NodeIndexType node);
435 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
438 void Build(std::vector<ArcIndexType>* permutation);
441 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
444 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
449 NodeIndexType last_tail_seen_;
450 std::vector<ArcIndexType> start_;
451 std::vector<NodeIndexType> head_;
452 std::vector<NodeIndexType> tail_;
461template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
463 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
485 class OutgoingOrOppositeIncomingArcIterator;
486 class OppositeIncomingArcIterator;
487 class IncomingArcIterator;
488 class OutgoingArcIterator;
489 class OutgoingHeadIterator;
492 ArcIndexType
OutDegree(NodeIndexType node)
const;
493 ArcIndexType
InDegree(NodeIndexType node)
const;
506 NodeIndexType node)
const;
508 NodeIndexType node, ArcIndexType from)
const;
510 NodeIndexType node, ArcIndexType from)
const;
513 ArcIndexType from)
const;
515 NodeIndexType node, ArcIndexType from)
const;
522 NodeIndexType
Head(ArcIndexType arc)
const;
523 NodeIndexType
Tail(ArcIndexType arc)
const;
527 void AddNode(NodeIndexType node);
528 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
531 void Build(std::vector<ArcIndexType>* permutation);
534 std::vector<ArcIndexType> start_;
535 std::vector<ArcIndexType> reverse_start_;
549template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
551 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
570 class OutgoingOrOppositeIncomingArcIterator;
571 class OppositeIncomingArcIterator;
572 class IncomingArcIterator;
573 class OutgoingArcIterator;
576 ArcIndexType
OutDegree(NodeIndexType node)
const;
577 ArcIndexType
InDegree(NodeIndexType node)
const;
584 NodeIndexType node)
const;
586 NodeIndexType node, ArcIndexType from)
const;
588 NodeIndexType node, ArcIndexType from)
const;
591 ArcIndexType from)
const;
593 NodeIndexType node, ArcIndexType from)
const;
602 NodeIndexType
Head(ArcIndexType arc)
const;
603 NodeIndexType
Tail(ArcIndexType arc)
const;
606 void AddNode(NodeIndexType node);
607 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
610 void Build(std::vector<ArcIndexType>* permutation);
613 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
616 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
618 ArcIndexType ReverseArcLimit(NodeIndexType node)
const {
621 return node + 1 < num_nodes_ ? reverse_start_[node + 1] : 0;
625 std::vector<ArcIndexType> start_;
626 std::vector<ArcIndexType> reverse_start_;
627 SVector<NodeIndexType> head_;
628 SVector<ArcIndexType> opposite_;
637template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
639 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
658 class OutgoingOrOppositeIncomingArcIterator;
659 class OppositeIncomingArcIterator;
660 class IncomingArcIterator;
661 class OutgoingArcIterator;
663 ArcIndexType
OutDegree(NodeIndexType node)
const;
664 ArcIndexType
InDegree(NodeIndexType node)
const;
671 NodeIndexType node)
const;
673 NodeIndexType node, ArcIndexType from)
const;
675 NodeIndexType node, ArcIndexType from)
const;
678 ArcIndexType from)
const;
680 NodeIndexType node, ArcIndexType from)
const;
689 NodeIndexType
Head(ArcIndexType arc)
const;
690 NodeIndexType
Tail(ArcIndexType arc)
const;
693 void AddNode(NodeIndexType node);
694 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
697 void Build(std::vector<ArcIndexType>* permutation);
700 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
703 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
707 std::vector<ArcIndexType> start_;
708 std::vector<ArcIndexType> reverse_start_;
709 std::vector<ArcIndexType> next_;
710 SVector<NodeIndexType> head_;
726template <
class IntVector,
class Array,
class ElementType>
728 Array* array_to_permute,
729 ElementType unused) {
730 std::vector<ElementType> temp(permutation.size());
731 for (
int i = 0; i < permutation.size(); ++i) {
732 temp[i] = (*array_to_permute)[i];
734 for (
int i = 0; i < permutation.size(); ++i) {
735 (*array_to_permute)[permutation[i]] = temp[i];
739template <
class IntVector,
class Array>
740void Permute(
const IntVector& permutation, Array* array_to_permute) {
741 if (permutation.empty()) {
745 (*array_to_permute)[0]);
750template <
class IntVector>
752 std::vector<bool>* array_to_permute) {
753 if (permutation.empty()) {
777 SVector() : base_(nullptr), size_(0), capacity_(0) {}
784 if (capacity_ < other.size_) {
788 capacity_ = other.size_;
789 base_ = Allocate(capacity_);
790 CHECK(base_ !=
nullptr);
797 for (
int i = -size_; i < size_; ++i) {
798 new (base_ + i) T(other.base_[i]);
816 DCHECK_GE(n, -size_);
822 DCHECK_GE(n, -size_);
828 for (
int i = -n; i < -size_; ++i) {
831 for (
int i = size_; i < n; ++i) {
834 for (
int i = -size_; i < -n; ++i) {
837 for (
int i = n; i < size_; ++i) {
845 T*
data()
const {
return base_; }
848 std::swap(base_, x.base_);
849 std::swap(size_, x.size_);
850 std::swap(capacity_, x.capacity_);
857 const int new_capacity = std::min(n,
max_size());
858 T* new_storage = Allocate(new_capacity);
859 CHECK(new_storage !=
nullptr);
860 T* new_base = new_storage + new_capacity;
863 for (
int i = -size_; i < size_; ++i) {
864 new (new_base + i) T(std::move(base_[i]));
866 int saved_size = size_;
870 capacity_ = new_capacity;
876 void grow(
const T& left = T(),
const T& right = T()) {
877 if (size_ == capacity_) {
883 new (base_ + size_) T(right_copy);
884 new (base_ - size_ - 1) T(left_copy);
887 new (base_ + size_) T(right);
888 new (base_ - size_ - 1) T(left);
893 int size()
const {
return size_; }
897 int max_size()
const {
return std::numeric_limits<int>::max(); }
900 if (base_ ==
nullptr)
return;
903 free(base_ - capacity_);
911 return absl::IgnoreLeak(
912 static_cast<T*
>(malloc(2LL *
capacity *
sizeof(T))));
915 int NewCapacity(
int delta) {
917 double candidate = 1.3 *
static_cast<double>(capacity_);
918 if (candidate >
static_cast<double>(
max_size())) {
919 candidate =
static_cast<double>(
max_size());
921 int new_capacity =
static_cast<int>(candidate);
922 if (new_capacity > capacity_ + delta) {
925 return capacity_ + delta;
935template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
936IntegerRange<NodeIndexType>
941template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
947template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
950 std::numeric_limits<NodeIndexType>::max();
952template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
955 std::numeric_limits<ArcIndexType>::max();
957template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
962 return node_capacity_ > num_nodes_ ? node_capacity_ : num_nodes_;
965template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
969 return arc_capacity_ > num_arcs_ ? arc_capacity_ : num_arcs_;
972template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
973void BaseGraph<NodeIndexType, ArcIndexType,
974 HasReverseArcs>::FreezeCapacities() {
977 const_capacities_ =
true;
978 node_capacity_ = std::max(node_capacity_, num_nodes_);
979 arc_capacity_ = std::max(arc_capacity_, num_arcs_);
984template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
987 ArcIndexType sum = 0;
988 for (
int i = 0; i < num_nodes_; ++i) {
989 ArcIndexType temp = (*v)[i];
993 DCHECK(sum == num_arcs_);
1001template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
1004 std::vector<ArcIndexType>* start,
1005 std::vector<ArcIndexType>* permutation) {
1009 start->assign(num_nodes_, 0);
1010 int last_tail_seen = 0;
1011 bool permutation_needed =
false;
1012 for (
int i = 0; i < num_arcs_; ++i) {
1013 NodeIndexType tail = (*head)[i];
1014 if (!permutation_needed) {
1015 permutation_needed = tail < last_tail_seen;
1016 last_tail_seen = tail;
1020 ComputeCumulativeSum(start);
1024 if (!permutation_needed) {
1025 for (
int i = 0; i < num_arcs_; ++i) {
1026 (*head)[i] = (*head)[~i];
1028 if (permutation !=
nullptr) {
1029 permutation->clear();
1036 std::vector<ArcIndexType> perm(num_arcs_);
1037 for (
int i = 0; i < num_arcs_; ++i) {
1038 perm[i] = (*start)[(*head)[i]]++;
1042 for (
int i = num_nodes_ - 1; i > 0; --i) {
1043 (*start)[i] = (*start)[i - 1];
1049 for (
int i = 0; i < num_arcs_; ++i) {
1050 (*head)[perm[i]] = (*head)[~i];
1052 if (permutation !=
nullptr) {
1053 permutation->swap(perm);
1066#define DEFINE_RANGE_BASED_ARC_ITERATION(c, t, e) \
1067 template <typename NodeIndexType, typename ArcIndexType> \
1068 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1069 c<NodeIndexType, ArcIndexType>::t##Arcs(NodeIndexType node) const { \
1070 return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node), \
1071 t##ArcIterator(*this, node, e)); \
1073 template <typename NodeIndexType, typename ArcIndexType> \
1074 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1075 c<NodeIndexType, ArcIndexType>::t##ArcsStartingFrom( \
1076 NodeIndexType node, ArcIndexType from) const { \
1077 return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node, from), \
1078 t##ArcIterator(*this, node, e)); \
1083#define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name) \
1084 using iterator_category = std::input_iterator_tag; \
1085 using difference_type = ptrdiff_t; \
1086 using pointer = const ArcIndexType*; \
1087 using reference = const ArcIndexType&; \
1088 using value_type = ArcIndexType; \
1089 bool operator!=(const iterator_class_name& other) const { \
1090 return this->index_ != other.index_; \
1092 bool operator==(const iterator_class_name& other) const { \
1093 return this->index_ == other.index_; \
1095 ArcIndexType operator*() const { return this->Index(); } \
1096 void operator++() { this->Next(); }
1102template <
typename NodeIndexType,
typename ArcIndexType>
1111template <
typename NodeIndexType,
typename ArcIndexType>
1113 ArcIndexType arc)
const {
1114 DCHECK(IsArcValid(arc));
1118template <
typename NodeIndexType,
typename ArcIndexType>
1120 ArcIndexType arc)
const {
1121 DCHECK(IsArcValid(arc));
1125template <
typename NodeIndexType,
typename ArcIndexType>
1127 NodeIndexType node)
const {
1128 ArcIndexType degree(0);
1129 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1133template <
typename NodeIndexType,
typename ArcIndexType>
1135 if (node < num_nodes_)
return;
1136 DCHECK(!const_capacities_ || node < node_capacity_);
1137 num_nodes_ = node + 1;
1138 start_.resize(num_nodes_, Base::kNilArc);
1141template <
typename NodeIndexType,
typename ArcIndexType>
1143 NodeIndexType tail, NodeIndexType head) {
1146 AddNode(tail > head ? tail : head);
1147 head_.push_back(head);
1148 tail_.push_back(tail);
1149 next_.push_back(start_[tail]);
1150 start_[tail] = num_arcs_;
1151 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1155template <
typename NodeIndexType,
typename ArcIndexType>
1157 Base::ReserveNodes(bound);
1158 if (bound <= num_nodes_)
return;
1159 start_.reserve(bound);
1162template <
typename NodeIndexType,
typename ArcIndexType>
1164 Base::ReserveArcs(bound);
1165 if (bound <= num_arcs_)
return;
1166 head_.reserve(bound);
1167 tail_.reserve(bound);
1168 next_.reserve(bound);
1171template <
typename NodeIndexType,
typename ArcIndexType>
1173 std::vector<ArcIndexType>* permutation) {
1174 if (permutation !=
nullptr) {
1175 permutation->clear();
1179template <
typename NodeIndexType,
typename ArcIndexType>
1183 : graph_(graph), index_(graph.start_[node]) {
1188 : graph_(graph), index_(arc) {
1193 ArcIndexType
Index()
const {
return index_; }
1196 index_ = graph_.next_[index_];
1203 ArcIndexType index_;
1206template <
typename NodeIndexType,
typename ArcIndexType>
1216 : graph_(graph), index_(graph.start_[node]) {
1221 : graph_(graph), index_(arc) {
1226 NodeIndexType
Index()
const {
return graph_.Head(index_); }
1229 index_ = graph_.next_[index_];
1235 return index_ != other.index_;
1242 ArcIndexType index_;
1249template <
typename NodeIndexType,
typename ArcIndexType>
1253 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1256template <
typename NodeIndexType,
typename ArcIndexType>
1258 NodeIndexType node)
const {
1259 return DirectArcLimit(node) - start_[node];
1262template <
typename NodeIndexType,
typename ArcIndexType>
1264 NodeIndexType bound) {
1265 Base::ReserveNodes(bound);
1266 if (bound <= num_nodes_)
return;
1267 start_.reserve(bound);
1270template <
typename NodeIndexType,
typename ArcIndexType>
1272 Base::ReserveArcs(bound);
1273 if (bound <= num_arcs_)
return;
1274 head_.reserve(bound);
1275 tail_.reserve(bound);
1278template <
typename NodeIndexType,
typename ArcIndexType>
1280 if (node < num_nodes_)
return;
1281 DCHECK(!const_capacities_ || node < node_capacity_) << node;
1282 num_nodes_ = node + 1;
1283 start_.resize(num_nodes_, 0);
1286template <
typename NodeIndexType,
typename ArcIndexType>
1288 NodeIndexType tail, NodeIndexType head) {
1292 AddNode(tail > head ? tail : head);
1293 if (arc_in_order_) {
1294 if (tail >= last_tail_seen_) {
1296 last_tail_seen_ = tail;
1298 arc_in_order_ =
false;
1301 tail_.push_back(tail);
1302 head_.push_back(head);
1303 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1307template <
typename NodeIndexType,
typename ArcIndexType>
1309 ArcIndexType arc)
const {
1310 DCHECK(IsArcValid(arc));
1314template <
typename NodeIndexType,
typename ArcIndexType>
1316 ArcIndexType arc)
const {
1317 DCHECK(IsArcValid(arc));
1333template <
typename NodeIndexType,
typename ArcIndexType>
1335 std::vector<ArcIndexType>* permutation) {
1337 if (is_built_)
return;
1339 node_capacity_ = num_nodes_;
1340 arc_capacity_ = num_arcs_;
1341 this->FreezeCapacities();
1344 if (arc_in_order_) {
1345 if (permutation !=
nullptr) {
1346 permutation->clear();
1348 this->ComputeCumulativeSum(&start_);
1354 start_.assign(num_nodes_, 0);
1355 for (
int i = 0; i < num_arcs_; ++i) {
1358 this->ComputeCumulativeSum(&start_);
1362 std::vector<ArcIndexType> perm(num_arcs_);
1363 for (
int i = 0; i < num_arcs_; ++i) {
1364 perm[i] = start_[tail_[i]]++;
1368 CHECK_EQ(tail_.size(), num_arcs_);
1370 for (
int i = 0; i < num_arcs_; ++i) {
1371 head_[perm[i]] = tail_[i];
1374 if (permutation !=
nullptr) {
1375 permutation->swap(perm);
1379 for (
int i = num_nodes_ - 1; i > 0; --i) {
1380 start_[i] = start_[i - 1];
1385 for (
const NodeIndexType node : Base::AllNodes()) {
1386 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1392template <
typename NodeIndexType,
typename ArcIndexType>
1396 : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
1399 : index_(arc), limit_(graph.DirectArcLimit(node)) {
1400 DCHECK_GE(arc, graph.start_[node]);
1403 bool Ok()
const {
return index_ < limit_; }
1404 ArcIndexType
Index()
const {
return index_; }
1420 ArcIndexType index_;
1421 const ArcIndexType limit_;
1429 OutgoingOrOppositeIncoming, Base::kNilArc);
1433template <
typename NodeIndexType,
typename ArcIndexType>
1435 NodeIndexType, ArcIndexType>::OutgoingHeadIterator>
1437 NodeIndexType node)
const {
1443template <
typename NodeIndexType,
typename ArcIndexType>
1445 NodeIndexType node)
const {
1446 ArcIndexType degree(0);
1447 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1451template <
typename NodeIndexType,
typename ArcIndexType>
1453 NodeIndexType node)
const {
1454 ArcIndexType degree(0);
1455 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1459template <
typename NodeIndexType,
typename ArcIndexType>
1461 ArcIndexType arc)
const {
1462 DCHECK(IsArcValid(arc));
1466template <
typename NodeIndexType,
typename ArcIndexType>
1468 ArcIndexType arc)
const {
1469 DCHECK(IsArcValid(arc));
1473template <
typename NodeIndexType,
typename ArcIndexType>
1475 ArcIndexType arc)
const {
1476 return head_[OppositeArc(arc)];
1479template <
typename NodeIndexType,
typename ArcIndexType>
1481 NodeIndexType bound) {
1482 Base::ReserveNodes(bound);
1483 if (bound <= num_nodes_)
return;
1484 start_.reserve(bound);
1485 reverse_start_.reserve(bound);
1488template <
typename NodeIndexType,
typename ArcIndexType>
1490 ArcIndexType bound) {
1491 Base::ReserveArcs(bound);
1492 if (bound <= num_arcs_)
return;
1493 head_.reserve(bound);
1494 next_.reserve(bound);
1497template <
typename NodeIndexType,
typename ArcIndexType>
1499 NodeIndexType node) {
1500 if (node < num_nodes_)
return;
1501 DCHECK(!const_capacities_ || node < node_capacity_);
1502 num_nodes_ = node + 1;
1503 start_.resize(num_nodes_, Base::kNilArc);
1504 reverse_start_.resize(num_nodes_, Base::kNilArc);
1507template <
typename NodeIndexType,
typename ArcIndexType>
1509 NodeIndexType tail, NodeIndexType head) {
1512 AddNode(tail > head ? tail : head);
1513 head_.grow(tail, head);
1514 next_.grow(reverse_start_[head], start_[tail]);
1515 start_[tail] = num_arcs_;
1516 reverse_start_[head] = ~num_arcs_;
1517 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1521template <
typename NodeIndexType,
typename ArcIndexType>
1523 std::vector<ArcIndexType>* permutation) {
1524 if (permutation !=
nullptr) {
1525 permutation->clear();
1529template <
typename NodeIndexType,
typename ArcIndexType>
1533 : graph_(graph), index_(graph.start_[node]) {
1538 : graph_(graph), index_(arc) {
1544 ArcIndexType
Index()
const {
return index_; }
1547 index_ = graph_.next_[index_];
1554 ArcIndexType index_;
1557template <
typename NodeIndexType,
typename ArcIndexType>
1563 : graph_(graph), index_(graph.reverse_start_[node]) {
1567 NodeIndexType node, ArcIndexType arc)
1568 : graph_(graph), index_(arc) {
1575 ArcIndexType
Index()
const {
return index_; }
1578 index_ = graph_.next_[index_];
1588template <
typename NodeIndexType,
typename ArcIndexType>
1604 : this->graph_.OppositeArc(this->index_);
1610template <
typename NodeIndexType,
typename ArcIndexType>
1616 : graph_(graph), index_(graph.reverse_start_[node]), node_(node) {
1621 NodeIndexType node, ArcIndexType arc)
1622 : graph_(graph), index_(arc), node_(node) {
1628 ArcIndexType
Index()
const {
return index_; }
1632 index_ = graph_.next_[index_];
1634 index_ = graph_.start_[node_];
1637 index_ = graph_.next_[index_];
1645 ArcIndexType index_;
1646 const NodeIndexType node_;
1649template <
typename NodeIndexType,
typename ArcIndexType>
1653 : graph_(&graph), index_(graph.start_[node]) {
1658 : graph_(&graph), index_(arc) {
1664 ArcIndexType
Index()
const {
return graph_->Head(index_); }
1667 index_ = graph_->next_[index_];
1674 ArcIndexType index_;
1680 DirectArcLimit(node));
1682 ReverseArcLimit(node));
1684 OutgoingOrOppositeIncoming,
1685 DirectArcLimit(node));
1687 ReverseArcLimit(node));
1689template <
typename NodeIndexType,
typename ArcIndexType>
1691 NodeIndexType node)
const {
1692 return DirectArcLimit(node) - start_[node];
1695template <
typename NodeIndexType,
typename ArcIndexType>
1697 NodeIndexType node)
const {
1698 return ReverseArcLimit(node) - reverse_start_[node];
1701template <
typename NodeIndexType,
typename ArcIndexType>
1704 NodeIndexType node)
const {
1706 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1709template <
typename NodeIndexType,
typename ArcIndexType>
1711 ArcIndexType arc)
const {
1713 DCHECK(IsArcValid(arc));
1714 return opposite_[arc];
1717template <
typename NodeIndexType,
typename ArcIndexType>
1719 ArcIndexType arc)
const {
1721 DCHECK(IsArcValid(arc));
1725template <
typename NodeIndexType,
typename ArcIndexType>
1727 ArcIndexType arc)
const {
1729 return head_[OppositeArc(arc)];
1732template <
typename NodeIndexType,
typename ArcIndexType>
1734 ArcIndexType bound) {
1735 Base::ReserveArcs(bound);
1736 if (bound <= num_arcs_)
return;
1737 head_.reserve(bound);
1740template <
typename NodeIndexType,
typename ArcIndexType>
1742 NodeIndexType node) {
1743 if (node < num_nodes_)
return;
1744 DCHECK(!const_capacities_ || node < node_capacity_);
1745 num_nodes_ = node + 1;
1748template <
typename NodeIndexType,
typename ArcIndexType>
1750 NodeIndexType tail, NodeIndexType head) {
1753 AddNode(tail > head ? tail : head);
1757 head_.grow(head, tail);
1758 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1762template <
typename NodeIndexType,
typename ArcIndexType>
1764 std::vector<ArcIndexType>* permutation) {
1766 if (is_built_)
return;
1768 node_capacity_ = num_nodes_;
1769 arc_capacity_ = num_arcs_;
1770 this->FreezeCapacities();
1771 this->BuildStartAndForwardHead(&head_, &start_, permutation);
1774 reverse_start_.assign(num_nodes_, 0);
1775 for (
int i = 0; i < num_arcs_; ++i) {
1776 reverse_start_[head_[i]]++;
1778 this->ComputeCumulativeSum(&reverse_start_);
1782 opposite_.reserve(num_arcs_);
1783 for (
int i = 0; i < num_arcs_; ++i) {
1785 opposite_.grow(0, reverse_start_[head_[i]]++ - num_arcs_);
1789 for (
int i = num_nodes_ - 1; i > 0; --i) {
1790 reverse_start_[i] = reverse_start_[i - 1] - num_arcs_;
1792 if (num_nodes_ != 0) {
1793 reverse_start_[0] = -num_arcs_;
1797 for (
int i = 0; i < num_arcs_; ++i) {
1798 opposite_[opposite_[i]] = i;
1800 for (
const NodeIndexType node : Base::AllNodes()) {
1801 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1802 head_[opposite_[arc]] = node;
1807template <
typename NodeIndexType,
typename ArcIndexType>
1811 : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
1814 : index_(arc), limit_(graph.DirectArcLimit(node)) {
1815 DCHECK_GE(arc, graph.start_[node]);
1818 bool Ok()
const {
return index_ < limit_; }
1819 ArcIndexType
Index()
const {
return index_; }
1830 ArcIndexType index_;
1831 const ArcIndexType limit_;
1834template <
typename NodeIndexType,
typename ArcIndexType>
1841 limit_(graph.ReverseArcLimit(node)),
1842 index_(graph.reverse_start_[node]) {
1844 DCHECK_LE(index_, limit_);
1847 NodeIndexType node, ArcIndexType arc)
1848 : graph_(graph), limit_(graph.ReverseArcLimit(node)), index_(arc) {
1850 DCHECK_GE(index_, graph.reverse_start_[node]);
1851 DCHECK_LE(index_, limit_);
1854 bool Ok()
const {
return index_ < limit_; }
1855 ArcIndexType
Index()
const {
return index_; }
1869template <
typename NodeIndexType,
typename ArcIndexType>
1878 arc == graph.ReverseArcLimit(node)
1879 ? graph.ReverseArcLimit(node)
1883 return this->index_ == this->limit_
1885 : this->graph_.OppositeArc(this->index_);
1891template <
typename NodeIndexType,
typename ArcIndexType>
1897 : index_(graph.reverse_start_[node]),
1898 first_limit_(graph.ReverseArcLimit(node)),
1899 next_start_(graph.start_[node]),
1900 limit_(graph.DirectArcLimit(node)) {
1901 if (index_ == first_limit_) index_ = next_start_;
1903 DCHECK((index_ < first_limit_) || (index_ >= next_start_));
1906 NodeIndexType node, ArcIndexType arc)
1908 first_limit_(graph.ReverseArcLimit(node)),
1909 next_start_(graph.start_[node]),
1910 limit_(graph.DirectArcLimit(node)) {
1912 DCHECK((index_ >= graph.reverse_start_[node] && index_ < first_limit_) ||
1913 (index_ >= next_start_));
1916 ArcIndexType
Index()
const {
return index_; }
1917 bool Ok()
const {
return index_ < limit_; }
1921 if (index_ == first_limit_) {
1922 index_ = next_start_;
1929 ArcIndexType index_;
1930 const ArcIndexType first_limit_;
1931 const ArcIndexType next_start_;
1932 const ArcIndexType limit_;
1938 DirectArcLimit(node));
1941 OutgoingOrOppositeIncoming,
1942 DirectArcLimit(node));
1946template <
typename NodeIndexType,
typename ArcIndexType>
1948 NodeIndexType node)
const {
1949 return DirectArcLimit(node) - start_[node];
1952template <
typename NodeIndexType,
typename ArcIndexType>
1954 NodeIndexType node)
const {
1955 ArcIndexType degree(0);
1956 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1960template <
typename NodeIndexType,
typename ArcIndexType>
1963 NodeIndexType node)
const {
1965 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1968template <
typename NodeIndexType,
typename ArcIndexType>
1970 ArcIndexType arc)
const {
1971 DCHECK(IsArcValid(arc));
1975template <
typename NodeIndexType,
typename ArcIndexType>
1977 ArcIndexType arc)
const {
1979 DCHECK(IsArcValid(arc));
1983template <
typename NodeIndexType,
typename ArcIndexType>
1985 ArcIndexType arc)
const {
1987 return head_[OppositeArc(arc)];
1990template <
typename NodeIndexType,
typename ArcIndexType>
1992 ArcIndexType bound) {
1993 Base::ReserveArcs(bound);
1994 if (bound <= num_arcs_)
return;
1995 head_.reserve(bound);
1998template <
typename NodeIndexType,
typename ArcIndexType>
2000 NodeIndexType node) {
2001 if (node < num_nodes_)
return;
2002 DCHECK(!const_capacities_ || node < node_capacity_);
2003 num_nodes_ = node + 1;
2006template <
typename NodeIndexType,
typename ArcIndexType>
2008 NodeIndexType tail, NodeIndexType head) {
2011 AddNode(tail > head ? tail : head);
2015 head_.grow(head, tail);
2016 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
2020template <
typename NodeIndexType,
typename ArcIndexType>
2022 std::vector<ArcIndexType>* permutation) {
2024 if (is_built_)
return;
2026 node_capacity_ = num_nodes_;
2027 arc_capacity_ = num_arcs_;
2028 this->FreezeCapacities();
2029 this->BuildStartAndForwardHead(&head_, &start_, permutation);
2032 for (
const NodeIndexType node : Base::AllNodes()) {
2033 for (
const ArcIndexType arc : OutgoingArcs(node)) {
2039 reverse_start_.assign(num_nodes_, Base::kNilArc);
2040 next_.reserve(num_arcs_);
2041 for (
const ArcIndexType arc : Base::AllForwardArcs()) {
2042 next_.push_back(reverse_start_[Head(arc)]);
2043 reverse_start_[Head(arc)] = -next_.size();
2047template <
typename NodeIndexType,
typename ArcIndexType>
2051 : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
2054 : index_(arc), limit_(graph.DirectArcLimit(node)) {
2055 DCHECK_GE(arc, graph.start_[node]);
2058 bool Ok()
const {
return index_ < limit_; }
2059 ArcIndexType
Index()
const {
return index_; }
2070 ArcIndexType index_;
2071 const ArcIndexType limit_;
2074template <
typename NodeIndexType,
typename ArcIndexType>
2081 DCHECK(graph.is_built_);
2083 index_ = graph.reverse_start_[node];
2086 NodeIndexType node, ArcIndexType arc)
2087 : graph_(&graph), index_(arc) {
2088 DCHECK(graph.is_built_);
2094 ArcIndexType
Index()
const {
return index_; }
2097 index_ = graph_->next_[~index_];
2107template <
typename NodeIndexType,
typename ArcIndexType>
2120 : this->graph_->OppositeArc(this->index_);
2126template <
typename NodeIndexType,
typename ArcIndexType>
2133 limit_ = graph.DirectArcLimit(node);
2134 index_ = graph.reverse_start_[node];
2135 restart_ = graph.start_[node];
2141 NodeIndexType node, ArcIndexType arc)
2143 limit_ = graph.DirectArcLimit(node);
2145 restart_ = graph.start_[node];
2150 return index_ < limit_;
2152 ArcIndexType
Index()
const {
return index_; }
2156 index_ = graph_->next_[graph_->OppositeArc(index_)];
2169 ArcIndexType index_;
2170 ArcIndexType restart_;
2171 ArcIndexType limit_;
2177template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
2195 NodeIndexType
Head(ArcIndexType arc)
const;
2196 NodeIndexType
Tail(ArcIndexType arc)
const;
2197 ArcIndexType
OutDegree(NodeIndexType node)
const;
2200 ArcIndexType from)
const;
2204template <
typename NodeIndexType,
typename ArcIndexType>
2206 ArcIndexType arc)
const {
2207 DCHECK(this->IsArcValid(arc));
2208 return arc % num_nodes_;
2211template <
typename NodeIndexType,
typename ArcIndexType>
2213 ArcIndexType arc)
const {
2214 DCHECK(this->IsArcValid(arc));
2215 return arc / num_nodes_;
2218template <
typename NodeIndexType,
typename ArcIndexType>
2220 NodeIndexType node)
const {
2224template <
typename NodeIndexType,
typename ArcIndexType>
2227 NodeIndexType node)
const {
2228 DCHECK_LT(node, num_nodes_);
2230 static_cast<ArcIndexType
>(num_nodes_) * node,
2231 static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
2234template <
typename NodeIndexType,
typename ArcIndexType>
2237 NodeIndexType node, ArcIndexType from)
const {
2238 DCHECK_LT(node, num_nodes_);
2240 from,
static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
2243template <
typename NodeIndexType,
typename ArcIndexType>
2246 NodeIndexType node)
const {
2247 DCHECK_LT(node, num_nodes_);
2254template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
2256 :
public BaseGraph<NodeIndexType, ArcIndexType, false> {
2270 : left_nodes_(left_nodes), right_nodes_(right_nodes) {
2271 this->
Reserve(left_nodes + right_nodes, left_nodes * right_nodes);
2273 num_nodes_ = left_nodes + right_nodes;
2274 num_arcs_ = left_nodes * right_nodes;
2277 NodeIndexType
Head(ArcIndexType arc)
const;
2278 NodeIndexType
Tail(ArcIndexType arc)
const;
2279 ArcIndexType
OutDegree(NodeIndexType node)
const;
2282 ArcIndexType from)
const;
2289 : index_(graph.right_nodes_ * node),
2290 limit_(node >= graph.left_nodes_ ? index_
2291 : graph.right_nodes_ * (node + 1)) {}
2293 bool Ok()
const {
return index_ < limit_; }
2294 ArcIndexType
Index()
const {
return index_; }
2298 ArcIndexType index_;
2299 const ArcIndexType limit_;
2303 const NodeIndexType left_nodes_;
2304 const NodeIndexType right_nodes_;
2307template <
typename NodeIndexType,
typename ArcIndexType>
2309 ArcIndexType arc)
const {
2310 DCHECK(this->IsArcValid(arc));
2311 return left_nodes_ + arc % right_nodes_;
2314template <
typename NodeIndexType,
typename ArcIndexType>
2316 ArcIndexType arc)
const {
2317 DCHECK(this->IsArcValid(arc));
2318 return arc / right_nodes_;
2321template <
typename NodeIndexType,
typename ArcIndexType>
2323 NodeIndexType node)
const {
2324 return (node < left_nodes_) ? right_nodes_ : 0;
2327template <
typename NodeIndexType,
typename ArcIndexType>
2330 NodeIndexType node)
const {
2331 if (node < left_nodes_) {
2333 right_nodes_ * (node + 1));
2339template <
typename NodeIndexType,
typename ArcIndexType>
2342 NodeIndexType node, ArcIndexType from)
const {
2343 if (node < left_nodes_) {
2350template <
typename NodeIndexType,
typename ArcIndexType>
2353 NodeIndexType node)
const {
2354 if (node < left_nodes_) {
2366#undef DEFINE_RANGE_BASED_ARC_ITERATION
2367#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
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
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)