155 #ifndef UTIL_GRAPH_GRAPH_H_
156 #define UTIL_GRAPH_GRAPH_H_
173 template <
typename T>
182 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32,
183 bool HasReverseArcs =
false>
263 template <
typename A,
typename B>
273 std::vector<ArcIndexType>* start,
274 std::vector<ArcIndexType>* permutation);
296 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
321 void AddNode(NodeIndexType node);
340 void Build(std::vector<ArcIndexType>* permutation);
343 class OutgoingArcIterator;
344 class OutgoingHeadIterator;
351 ArcIndexType
OutDegree(NodeIndexType node)
const;
361 NodeIndexType node, ArcIndexType from)
const;
369 NodeIndexType
Tail(ArcIndexType arc)
const;
370 NodeIndexType
Head(ArcIndexType arc)
const;
376 std::vector<ArcIndexType> start_;
377 std::vector<ArcIndexType> next_;
378 std::vector<NodeIndexType> head_;
379 std::vector<NodeIndexType> tail_;
395 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
406 StaticGraph() : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {}
408 : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {
415 class OutgoingArcIterator;
417 NodeIndexType
Head(ArcIndexType arc)
const;
418 NodeIndexType
Tail(ArcIndexType arc)
const;
419 ArcIndexType
OutDegree(NodeIndexType node)
const;
422 NodeIndexType node, ArcIndexType from)
const;
431 void AddNode(NodeIndexType node);
435 void Build(std::vector<ArcIndexType>* permutation);
438 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
441 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
446 NodeIndexType last_tail_seen_;
447 std::vector<ArcIndexType> start_;
448 std::vector<NodeIndexType> head_;
449 std::vector<NodeIndexType> tail_;
458 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
460 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
482 class OutgoingOrOppositeIncomingArcIterator;
483 class OppositeIncomingArcIterator;
484 class IncomingArcIterator;
485 class OutgoingArcIterator;
486 class OutgoingHeadIterator;
503 NodeIndexType node)
const;
505 NodeIndexType node, ArcIndexType from)
const;
507 NodeIndexType node, ArcIndexType from)
const;
510 ArcIndexType from)
const;
512 NodeIndexType node, ArcIndexType from)
const;
519 NodeIndexType
Head(ArcIndexType arc)
const;
520 NodeIndexType
Tail(ArcIndexType arc)
const;
528 void Build(std::vector<ArcIndexType>* permutation);
531 std::vector<ArcIndexType> start_;
532 std::vector<ArcIndexType> reverse_start_;
546 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
548 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
567 class OutgoingOrOppositeIncomingArcIterator;
568 class OppositeIncomingArcIterator;
569 class IncomingArcIterator;
570 class OutgoingArcIterator;
573 ArcIndexType
OutDegree(NodeIndexType node)
const;
574 ArcIndexType
InDegree(NodeIndexType node)
const;
581 NodeIndexType node)
const;
583 NodeIndexType node, ArcIndexType from)
const;
585 NodeIndexType node, ArcIndexType from)
const;
588 ArcIndexType from)
const;
590 NodeIndexType node, ArcIndexType from)
const;
599 NodeIndexType
Head(ArcIndexType arc)
const;
600 NodeIndexType
Tail(ArcIndexType arc)
const;
603 void AddNode(NodeIndexType node);
607 void Build(std::vector<ArcIndexType>* permutation);
610 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
613 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
615 ArcIndexType ReverseArcLimit(NodeIndexType node)
const {
618 return node + 1 < num_nodes_ ? reverse_start_[node + 1] : 0;
622 std::vector<ArcIndexType> start_;
623 std::vector<ArcIndexType> reverse_start_;
624 SVector<NodeIndexType> head_;
625 SVector<ArcIndexType> opposite_;
634 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
636 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
655 class OutgoingOrOppositeIncomingArcIterator;
656 class OppositeIncomingArcIterator;
657 class IncomingArcIterator;
658 class OutgoingArcIterator;
660 ArcIndexType
OutDegree(NodeIndexType node)
const;
661 ArcIndexType
InDegree(NodeIndexType node)
const;
668 NodeIndexType node)
const;
670 NodeIndexType node, ArcIndexType from)
const;
672 NodeIndexType node, ArcIndexType from)
const;
675 ArcIndexType from)
const;
677 NodeIndexType node, ArcIndexType from)
const;
686 NodeIndexType
Head(ArcIndexType arc)
const;
687 NodeIndexType
Tail(ArcIndexType arc)
const;
690 void AddNode(NodeIndexType node);
694 void Build(std::vector<ArcIndexType>* permutation);
697 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
700 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
704 std::vector<ArcIndexType> start_;
705 std::vector<ArcIndexType> reverse_start_;
706 std::vector<ArcIndexType> next_;
707 SVector<NodeIndexType> head_;
723 template <
class IntVector,
class Array,
class ElementType>
725 Array* array_to_permute,
726 ElementType unused) {
727 std::vector<ElementType> temp(permutation.size());
728 for (
int i = 0; i < permutation.size(); ++i) {
729 temp[i] = (*array_to_permute)[i];
731 for (
int i = 0; i < permutation.size(); ++i) {
732 (*array_to_permute)[permutation[i]] = temp[i];
736 template <
class IntVector,
class Array>
737 void Permute(
const IntVector& permutation, Array* array_to_permute) {
738 if (permutation.empty()) {
742 (*array_to_permute)[0]);
747 template <
class IntVector>
749 std::vector<bool>* array_to_permute) {
750 if (permutation.empty()) {
771 template <
typename T>
774 SVector() : base_(nullptr), size_(0), capacity_(0) {}
781 if (capacity_ < other.size_) {
785 capacity_ = other.size_;
786 base_ =
static_cast<T*
>(
malloc(2LL * capacity_ *
sizeof(T)));
787 CHECK(base_ !=
nullptr);
794 for (
int i = -size_; i < size_; ++i) {
795 new (base_ + i) T(other.base_[i]);
825 for (
int i = -n; i < -size_; ++i) {
828 for (
int i = size_; i < n; ++i) {
831 for (
int i = -size_; i < -n; ++i) {
834 for (
int i = n; i < size_; ++i) {
842 T*
data()
const {
return base_; }
845 std::swap(base_, x.base_);
846 std::swap(size_, x.size_);
847 std::swap(capacity_, x.capacity_);
855 T* new_storage =
static_cast<T*
>(
malloc(2LL * new_capacity *
sizeof(T)));
856 CHECK(new_storage !=
nullptr);
857 T* new_base = new_storage + new_capacity;
860 for (
int i = -size_; i < size_; ++i) {
861 new (new_base + i) T(std::move(base_[i]));
863 int saved_size = size_;
867 capacity_ = new_capacity;
873 void grow(
const T& left = T(),
const T& right = T()) {
874 if (size_ == capacity_) {
880 new (base_ + size_) T(right_copy);
881 new (base_ - size_ - 1) T(left_copy);
884 new (base_ + size_) T(right);
885 new (base_ - size_ - 1) T(left);
890 int size()
const {
return size_; }
897 if (base_ ==
nullptr)
return;
900 free(base_ - capacity_);
907 int NewCapacity(
int delta) {
909 double candidate = 1.3 *
static_cast<double>(capacity_);
910 if (candidate >
static_cast<double>(
max_size())) {
911 candidate =
static_cast<double>(
max_size());
913 int new_capacity =
static_cast<int>(candidate);
914 if (new_capacity > capacity_ +
delta) {
917 return capacity_ +
delta;
927 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
928 IntegerRange<NodeIndexType>
933 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
939 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
944 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
949 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
954 return node_capacity_ > num_nodes_ ? node_capacity_ : num_nodes_;
957 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
961 return arc_capacity_ > num_arcs_ ? arc_capacity_ : num_arcs_;
964 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
965 void BaseGraph<NodeIndexType, ArcIndexType,
966 HasReverseArcs>::FreezeCapacities() {
969 const_capacities_ =
true;
970 node_capacity_ =
std::max(node_capacity_, num_nodes_);
971 arc_capacity_ =
std::max(arc_capacity_, num_arcs_);
976 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
979 ArcIndexType sum = 0;
980 for (
int i = 0; i < num_nodes_; ++i) {
981 ArcIndexType temp = (*v)[i];
993 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
996 std::vector<ArcIndexType>* start,
997 std::vector<ArcIndexType>* permutation) {
1001 start->assign(num_nodes_, 0);
1002 int last_tail_seen = 0;
1003 bool permutation_needed =
false;
1004 for (
int i = 0; i < num_arcs_; ++i) {
1005 NodeIndexType
tail = (*head)[i];
1006 if (!permutation_needed) {
1007 permutation_needed =
tail < last_tail_seen;
1008 last_tail_seen =
tail;
1012 ComputeCumulativeSum(start);
1016 if (!permutation_needed) {
1017 for (
int i = 0; i < num_arcs_; ++i) {
1018 (*head)[i] = (*head)[~i];
1020 if (permutation !=
nullptr) {
1021 permutation->clear();
1028 std::vector<ArcIndexType> perm(num_arcs_);
1029 for (
int i = 0; i < num_arcs_; ++i) {
1030 perm[i] = (*start)[(*head)[i]]++;
1034 for (
int i = num_nodes_ - 1; i > 0; --i) {
1035 (*start)[i] = (*start)[i - 1];
1041 for (
int i = 0; i < num_arcs_; ++i) {
1042 (*head)[perm[i]] = (*head)[~i];
1044 if (permutation !=
nullptr) {
1045 permutation->swap(perm);
1058 #define DEFINE_RANGE_BASED_ARC_ITERATION(c, t, e) \
1059 template <typename NodeIndexType, typename ArcIndexType> \
1060 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1061 c<NodeIndexType, ArcIndexType>::t##Arcs(NodeIndexType node) const { \
1062 return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node), \
1063 t##ArcIterator(*this, node, e)); \
1065 template <typename NodeIndexType, typename ArcIndexType> \
1066 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1067 c<NodeIndexType, ArcIndexType>::t##ArcsStartingFrom( \
1068 NodeIndexType node, ArcIndexType from) const { \
1069 return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node, from), \
1070 t##ArcIterator(*this, node, e)); \
1075 #define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name) \
1076 using iterator_category = std::input_iterator_tag; \
1077 using difference_type = ptrdiff_t; \
1078 using pointer = const ArcIndexType*; \
1079 using reference = const ArcIndexType&; \
1080 using value_type = ArcIndexType; \
1081 bool operator!=(const iterator_class_name& other) const { \
1082 return this->index_ != other.index_; \
1084 bool operator==(const iterator_class_name& other) const { \
1085 return this->index_ == other.index_; \
1087 ArcIndexType operator*() const { return this->Index(); } \
1088 void operator++() { this->Next(); }
1094 template <
typename NodeIndexType,
typename ArcIndexType>
1103 template <
typename NodeIndexType,
typename ArcIndexType>
1105 ArcIndexType arc)
const {
1110 template <
typename NodeIndexType,
typename ArcIndexType>
1112 ArcIndexType arc)
const {
1117 template <
typename NodeIndexType,
typename ArcIndexType>
1119 NodeIndexType node)
const {
1120 ArcIndexType degree(0);
1121 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1125 template <
typename NodeIndexType,
typename ArcIndexType>
1127 if (node < num_nodes_)
return;
1128 DCHECK(!const_capacities_ || node < node_capacity_);
1129 num_nodes_ = node + 1;
1130 start_.resize(num_nodes_, Base::kNilArc);
1133 template <
typename NodeIndexType,
typename ArcIndexType>
1135 NodeIndexType
tail, NodeIndexType
head) {
1139 head_.push_back(
head);
1140 tail_.push_back(
tail);
1141 next_.push_back(start_[
tail]);
1142 start_[
tail] = num_arcs_;
1143 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1147 template <
typename NodeIndexType,
typename ArcIndexType>
1149 Base::ReserveNodes(
bound);
1150 if (
bound <= num_nodes_)
return;
1151 start_.reserve(
bound);
1154 template <
typename NodeIndexType,
typename ArcIndexType>
1156 Base::ReserveArcs(
bound);
1157 if (
bound <= num_arcs_)
return;
1158 head_.reserve(
bound);
1159 tail_.reserve(
bound);
1160 next_.reserve(
bound);
1163 template <
typename NodeIndexType,
typename ArcIndexType>
1165 std::vector<ArcIndexType>* permutation) {
1166 if (permutation !=
nullptr) {
1167 permutation->clear();
1171 template <
typename NodeIndexType,
typename ArcIndexType>
1175 : graph_(graph), index_(graph.start_[node]) {
1180 : graph_(graph), index_(arc) {
1185 ArcIndexType
Index()
const {
return index_; }
1188 index_ = graph_.next_[index_];
1195 ArcIndexType index_;
1198 template <
typename NodeIndexType,
typename ArcIndexType>
1208 : graph_(graph), index_(graph.start_[node]) {
1213 : graph_(graph), index_(arc) {
1218 NodeIndexType
Index()
const {
return graph_.Head(index_); }
1221 index_ = graph_.next_[index_];
1227 return index_ != other.index_;
1234 ArcIndexType index_;
1241 template <
typename NodeIndexType,
typename ArcIndexType>
1245 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1248 template <
typename NodeIndexType,
typename ArcIndexType>
1250 NodeIndexType node)
const {
1251 return DirectArcLimit(node) - start_[node];
1254 template <
typename NodeIndexType,
typename ArcIndexType>
1256 NodeIndexType
bound) {
1257 Base::ReserveNodes(
bound);
1258 if (
bound <= num_nodes_)
return;
1259 start_.reserve(
bound);
1262 template <
typename NodeIndexType,
typename ArcIndexType>
1264 Base::ReserveArcs(
bound);
1265 if (
bound <= num_arcs_)
return;
1266 head_.reserve(
bound);
1267 tail_.reserve(
bound);
1270 template <
typename NodeIndexType,
typename ArcIndexType>
1272 if (node < num_nodes_)
return;
1273 DCHECK(!const_capacities_ || node < node_capacity_) << node;
1274 num_nodes_ = node + 1;
1275 start_.resize(num_nodes_, 0);
1278 template <
typename NodeIndexType,
typename ArcIndexType>
1280 NodeIndexType
tail, NodeIndexType
head) {
1285 if (arc_in_order_) {
1286 if (
tail >= last_tail_seen_) {
1288 last_tail_seen_ =
tail;
1290 arc_in_order_ =
false;
1293 tail_.push_back(
tail);
1294 head_.push_back(
head);
1295 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1299 template <
typename NodeIndexType,
typename ArcIndexType>
1301 ArcIndexType arc)
const {
1306 template <
typename NodeIndexType,
typename ArcIndexType>
1308 ArcIndexType arc)
const {
1325 template <
typename NodeIndexType,
typename ArcIndexType>
1327 std::vector<ArcIndexType>* permutation) {
1329 if (is_built_)
return;
1331 node_capacity_ = num_nodes_;
1332 arc_capacity_ = num_arcs_;
1333 this->FreezeCapacities();
1336 if (arc_in_order_) {
1337 if (permutation !=
nullptr) {
1338 permutation->clear();
1340 this->ComputeCumulativeSum(&start_);
1346 start_.assign(num_nodes_, 0);
1347 for (
int i = 0; i < num_arcs_; ++i) {
1350 this->ComputeCumulativeSum(&start_);
1354 std::vector<ArcIndexType> perm(num_arcs_);
1355 for (
int i = 0; i < num_arcs_; ++i) {
1356 perm[i] = start_[tail_[i]]++;
1362 for (
int i = 0; i < num_arcs_; ++i) {
1363 head_[perm[i]] = tail_[i];
1366 if (permutation !=
nullptr) {
1367 permutation->swap(perm);
1371 for (
int i = num_nodes_ - 1; i > 0; --i) {
1372 start_[i] = start_[i - 1];
1377 for (
const NodeIndexType node : Base::AllNodes()) {
1378 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1384 template <
typename NodeIndexType,
typename ArcIndexType>
1388 : index_(graph.start_[node]),
limit_(graph.DirectArcLimit(node)) {}
1391 : index_(arc),
limit_(graph.DirectArcLimit(node)) {
1396 ArcIndexType
Index()
const {
return index_; }
1412 ArcIndexType index_;
1413 const ArcIndexType
limit_;
1421 OutgoingOrOppositeIncoming, Base::kNilArc);
1425 template <
typename NodeIndexType,
typename ArcIndexType>
1427 NodeIndexType, ArcIndexType>::OutgoingHeadIterator>
1429 NodeIndexType node)
const {
1435 template <
typename NodeIndexType,
typename ArcIndexType>
1437 NodeIndexType node)
const {
1438 ArcIndexType degree(0);
1439 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1443 template <
typename NodeIndexType,
typename ArcIndexType>
1445 NodeIndexType node)
const {
1446 ArcIndexType degree(0);
1447 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1451 template <
typename NodeIndexType,
typename ArcIndexType>
1453 ArcIndexType arc)
const {
1458 template <
typename NodeIndexType,
typename ArcIndexType>
1460 ArcIndexType arc)
const {
1465 template <
typename NodeIndexType,
typename ArcIndexType>
1467 ArcIndexType arc)
const {
1468 return head_[OppositeArc(arc)];
1471 template <
typename NodeIndexType,
typename ArcIndexType>
1473 NodeIndexType
bound) {
1474 Base::ReserveNodes(
bound);
1475 if (
bound <= num_nodes_)
return;
1476 start_.reserve(
bound);
1477 reverse_start_.reserve(
bound);
1480 template <
typename NodeIndexType,
typename ArcIndexType>
1482 ArcIndexType
bound) {
1483 Base::ReserveArcs(
bound);
1484 if (
bound <= num_arcs_)
return;
1485 head_.reserve(
bound);
1486 next_.reserve(
bound);
1489 template <
typename NodeIndexType,
typename ArcIndexType>
1491 NodeIndexType node) {
1492 if (node < num_nodes_)
return;
1493 DCHECK(!const_capacities_ || node < node_capacity_);
1494 num_nodes_ = node + 1;
1495 start_.resize(num_nodes_, Base::kNilArc);
1496 reverse_start_.resize(num_nodes_, Base::kNilArc);
1499 template <
typename NodeIndexType,
typename ArcIndexType>
1501 NodeIndexType
tail, NodeIndexType
head) {
1506 next_.grow(reverse_start_[
head], start_[
tail]);
1507 start_[
tail] = num_arcs_;
1508 reverse_start_[
head] = ~num_arcs_;
1509 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1513 template <
typename NodeIndexType,
typename ArcIndexType>
1515 std::vector<ArcIndexType>* permutation) {
1516 if (permutation !=
nullptr) {
1517 permutation->clear();
1521 template <
typename NodeIndexType,
typename ArcIndexType>
1525 : graph_(graph), index_(graph.start_[node]) {
1530 : graph_(graph), index_(arc) {
1536 ArcIndexType
Index()
const {
return index_; }
1539 index_ = graph_.next_[index_];
1546 ArcIndexType index_;
1549 template <
typename NodeIndexType,
typename ArcIndexType>
1555 : graph_(graph), index_(graph.reverse_start_[node]) {
1559 NodeIndexType node, ArcIndexType arc)
1560 : graph_(graph), index_(arc) {
1567 ArcIndexType
Index()
const {
return index_; }
1570 index_ = graph_.next_[index_];
1580 template <
typename NodeIndexType,
typename ArcIndexType>
1596 : this->graph_.OppositeArc(this->index_);
1602 template <
typename NodeIndexType,
typename ArcIndexType>
1608 : graph_(graph), index_(graph.reverse_start_[node]), node_(node) {
1613 NodeIndexType node, ArcIndexType arc)
1614 : graph_(graph), index_(arc), node_(node) {
1620 ArcIndexType
Index()
const {
return index_; }
1624 index_ = graph_.next_[index_];
1626 index_ = graph_.start_[node_];
1629 index_ = graph_.next_[index_];
1637 ArcIndexType index_;
1638 const NodeIndexType node_;
1641 template <
typename NodeIndexType,
typename ArcIndexType>
1645 : graph_(&graph), index_(graph.start_[node]) {
1650 : graph_(&graph), index_(arc) {
1656 ArcIndexType
Index()
const {
return graph_->Head(index_); }
1659 index_ = graph_->next_[index_];
1666 ArcIndexType index_;
1672 DirectArcLimit(node));
1674 ReverseArcLimit(node));
1676 OutgoingOrOppositeIncoming,
1677 DirectArcLimit(node));
1679 ReverseArcLimit(node));
1681 template <
typename NodeIndexType,
typename ArcIndexType>
1683 NodeIndexType node)
const {
1684 return DirectArcLimit(node) - start_[node];
1687 template <
typename NodeIndexType,
typename ArcIndexType>
1689 NodeIndexType node)
const {
1690 return ReverseArcLimit(node) - reverse_start_[node];
1693 template <
typename NodeIndexType,
typename ArcIndexType>
1696 NodeIndexType node)
const {
1698 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1701 template <
typename NodeIndexType,
typename ArcIndexType>
1703 ArcIndexType arc)
const {
1706 return opposite_[arc];
1709 template <
typename NodeIndexType,
typename ArcIndexType>
1711 ArcIndexType arc)
const {
1717 template <
typename NodeIndexType,
typename ArcIndexType>
1719 ArcIndexType arc)
const {
1721 return head_[OppositeArc(arc)];
1724 template <
typename NodeIndexType,
typename ArcIndexType>
1726 ArcIndexType
bound) {
1727 Base::ReserveArcs(
bound);
1728 if (
bound <= num_arcs_)
return;
1729 head_.reserve(
bound);
1732 template <
typename NodeIndexType,
typename ArcIndexType>
1734 NodeIndexType node) {
1735 if (node < num_nodes_)
return;
1736 DCHECK(!const_capacities_ || node < node_capacity_);
1737 num_nodes_ = node + 1;
1740 template <
typename NodeIndexType,
typename ArcIndexType>
1742 NodeIndexType
tail, NodeIndexType
head) {
1750 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1754 template <
typename NodeIndexType,
typename ArcIndexType>
1756 std::vector<ArcIndexType>* permutation) {
1758 if (is_built_)
return;
1760 node_capacity_ = num_nodes_;
1761 arc_capacity_ = num_arcs_;
1762 this->FreezeCapacities();
1763 this->BuildStartAndForwardHead(&head_, &start_, permutation);
1766 reverse_start_.assign(num_nodes_, 0);
1767 for (
int i = 0; i < num_arcs_; ++i) {
1768 reverse_start_[head_[i]]++;
1770 this->ComputeCumulativeSum(&reverse_start_);
1774 opposite_.reserve(num_arcs_);
1775 for (
int i = 0; i < num_arcs_; ++i) {
1777 opposite_.grow(0, reverse_start_[head_[i]]++ - num_arcs_);
1781 for (
int i = num_nodes_ - 1; i > 0; --i) {
1782 reverse_start_[i] = reverse_start_[i - 1] - num_arcs_;
1784 if (num_nodes_ != 0) {
1785 reverse_start_[0] = -num_arcs_;
1789 for (
int i = 0; i < num_arcs_; ++i) {
1790 opposite_[opposite_[i]] = i;
1792 for (
const NodeIndexType node : Base::AllNodes()) {
1793 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1794 head_[opposite_[arc]] = node;
1799 template <
typename NodeIndexType,
typename ArcIndexType>
1803 : index_(graph.start_[node]),
limit_(graph.DirectArcLimit(node)) {}
1806 : index_(arc),
limit_(graph.DirectArcLimit(node)) {
1811 ArcIndexType
Index()
const {
return index_; }
1822 ArcIndexType index_;
1823 const ArcIndexType
limit_;
1826 template <
typename NodeIndexType,
typename ArcIndexType>
1833 limit_(graph.ReverseArcLimit(node)),
1834 index_(graph.reverse_start_[node]) {
1839 NodeIndexType node, ArcIndexType arc)
1840 : graph_(graph),
limit_(graph.ReverseArcLimit(node)), index_(arc) {
1842 DCHECK_GE(index_, graph.reverse_start_[node]);
1847 ArcIndexType
Index()
const {
return index_; }
1861 template <
typename NodeIndexType,
typename ArcIndexType>
1870 arc == graph.ReverseArcLimit(node)
1871 ? graph.ReverseArcLimit(node)
1875 return this->index_ == this->
limit_
1877 : this->graph_.OppositeArc(this->index_);
1883 template <
typename NodeIndexType,
typename ArcIndexType>
1889 : index_(graph.reverse_start_[node]),
1890 first_limit_(graph.ReverseArcLimit(node)),
1891 next_start_(graph.start_[node]),
1892 limit_(graph.DirectArcLimit(node)) {
1893 if (index_ == first_limit_) index_ = next_start_;
1895 DCHECK((index_ < first_limit_) || (index_ >= next_start_));
1898 NodeIndexType node, ArcIndexType arc)
1900 first_limit_(graph.ReverseArcLimit(node)),
1901 next_start_(graph.start_[node]),
1902 limit_(graph.DirectArcLimit(node)) {
1904 DCHECK((index_ >= graph.reverse_start_[node] && index_ < first_limit_) ||
1905 (index_ >= next_start_));
1908 ArcIndexType
Index()
const {
return index_; }
1913 if (index_ == first_limit_) {
1914 index_ = next_start_;
1921 ArcIndexType index_;
1922 const ArcIndexType first_limit_;
1923 const ArcIndexType next_start_;
1924 const ArcIndexType
limit_;
1930 DirectArcLimit(node));
1933 OutgoingOrOppositeIncoming,
1934 DirectArcLimit(node));
1938 template <
typename NodeIndexType,
typename ArcIndexType>
1940 NodeIndexType node)
const {
1941 return DirectArcLimit(node) - start_[node];
1944 template <
typename NodeIndexType,
typename ArcIndexType>
1946 NodeIndexType node)
const {
1947 ArcIndexType degree(0);
1948 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1952 template <
typename NodeIndexType,
typename ArcIndexType>
1955 NodeIndexType node)
const {
1957 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1960 template <
typename NodeIndexType,
typename ArcIndexType>
1962 ArcIndexType arc)
const {
1967 template <
typename NodeIndexType,
typename ArcIndexType>
1969 ArcIndexType arc)
const {
1975 template <
typename NodeIndexType,
typename ArcIndexType>
1977 ArcIndexType arc)
const {
1979 return head_[OppositeArc(arc)];
1982 template <
typename NodeIndexType,
typename ArcIndexType>
1984 ArcIndexType
bound) {
1985 Base::ReserveArcs(
bound);
1986 if (
bound <= num_arcs_)
return;
1987 head_.reserve(
bound);
1990 template <
typename NodeIndexType,
typename ArcIndexType>
1992 NodeIndexType node) {
1993 if (node < num_nodes_)
return;
1994 DCHECK(!const_capacities_ || node < node_capacity_);
1995 num_nodes_ = node + 1;
1998 template <
typename NodeIndexType,
typename ArcIndexType>
2000 NodeIndexType
tail, NodeIndexType
head) {
2008 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
2012 template <
typename NodeIndexType,
typename ArcIndexType>
2014 std::vector<ArcIndexType>* permutation) {
2016 if (is_built_)
return;
2018 node_capacity_ = num_nodes_;
2019 arc_capacity_ = num_arcs_;
2020 this->FreezeCapacities();
2021 this->BuildStartAndForwardHead(&head_, &start_, permutation);
2024 for (
const NodeIndexType node : Base::AllNodes()) {
2025 for (
const ArcIndexType arc : OutgoingArcs(node)) {
2031 reverse_start_.assign(num_nodes_, Base::kNilArc);
2032 next_.reserve(num_arcs_);
2033 for (
const ArcIndexType arc : Base::AllForwardArcs()) {
2034 next_.push_back(reverse_start_[Head(arc)]);
2035 reverse_start_[Head(arc)] = -next_.size();
2039 template <
typename NodeIndexType,
typename ArcIndexType>
2043 : index_(graph.start_[node]),
limit_(graph.DirectArcLimit(node)) {}
2046 : index_(arc),
limit_(graph.DirectArcLimit(node)) {
2051 ArcIndexType
Index()
const {
return index_; }
2062 ArcIndexType index_;
2063 const ArcIndexType
limit_;
2066 template <
typename NodeIndexType,
typename ArcIndexType>
2075 index_ = graph.reverse_start_[node];
2078 NodeIndexType node, ArcIndexType arc)
2079 : graph_(&graph), index_(arc) {
2086 ArcIndexType
Index()
const {
return index_; }
2089 index_ = graph_->next_[~index_];
2099 template <
typename NodeIndexType,
typename ArcIndexType>
2112 : this->graph_->OppositeArc(this->index_);
2118 template <
typename NodeIndexType,
typename ArcIndexType>
2125 limit_ = graph.DirectArcLimit(node);
2126 index_ = graph.reverse_start_[node];
2127 restart_ = graph.start_[node];
2133 NodeIndexType node, ArcIndexType arc)
2135 limit_ = graph.DirectArcLimit(node);
2137 restart_ = graph.start_[node];
2144 ArcIndexType
Index()
const {
return index_; }
2148 index_ = graph_->next_[graph_->OppositeArc(index_)];
2161 ArcIndexType index_;
2162 ArcIndexType restart_;
2169 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
2187 NodeIndexType
Head(ArcIndexType arc)
const;
2188 NodeIndexType
Tail(ArcIndexType arc)
const;
2189 ArcIndexType
OutDegree(NodeIndexType node)
const;
2192 ArcIndexType from)
const;
2196 template <
typename NodeIndexType,
typename ArcIndexType>
2198 ArcIndexType arc)
const {
2199 DCHECK(this->IsArcValid(arc));
2200 return arc % num_nodes_;
2203 template <
typename NodeIndexType,
typename ArcIndexType>
2205 ArcIndexType arc)
const {
2206 DCHECK(this->IsArcValid(arc));
2207 return arc / num_nodes_;
2210 template <
typename NodeIndexType,
typename ArcIndexType>
2212 NodeIndexType node)
const {
2216 template <
typename NodeIndexType,
typename ArcIndexType>
2219 NodeIndexType node)
const {
2222 static_cast<ArcIndexType
>(num_nodes_) * node,
2223 static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
2226 template <
typename NodeIndexType,
typename ArcIndexType>
2229 NodeIndexType node, ArcIndexType from)
const {
2232 from,
static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
2235 template <
typename NodeIndexType,
typename ArcIndexType>
2238 NodeIndexType node)
const {
2246 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
2248 :
public BaseGraph<NodeIndexType, ArcIndexType, false> {
2262 : left_nodes_(left_nodes), right_nodes_(right_nodes) {
2263 this->
Reserve(left_nodes + right_nodes, left_nodes * right_nodes);
2265 num_nodes_ = left_nodes + right_nodes;
2266 num_arcs_ = left_nodes * right_nodes;
2269 NodeIndexType
Head(ArcIndexType arc)
const;
2270 NodeIndexType
Tail(ArcIndexType arc)
const;
2271 ArcIndexType
OutDegree(NodeIndexType node)
const;
2274 ArcIndexType from)
const;
2281 : index_(graph.right_nodes_ * node),
2282 limit_(node >= graph.left_nodes_ ? index_
2283 : graph.right_nodes_ * (node + 1)) {}
2285 bool Ok()
const {
return index_ < limit_; }
2286 ArcIndexType
Index()
const {
return index_; }
2290 ArcIndexType index_;
2291 const ArcIndexType limit_;
2295 const NodeIndexType left_nodes_;
2296 const NodeIndexType right_nodes_;
2299 template <
typename NodeIndexType,
typename ArcIndexType>
2301 ArcIndexType arc)
const {
2302 DCHECK(this->IsArcValid(arc));
2303 return left_nodes_ + arc % right_nodes_;
2306 template <
typename NodeIndexType,
typename ArcIndexType>
2308 ArcIndexType arc)
const {
2309 DCHECK(this->IsArcValid(arc));
2310 return arc / right_nodes_;
2313 template <
typename NodeIndexType,
typename ArcIndexType>
2315 NodeIndexType node)
const {
2316 return (node < left_nodes_) ? right_nodes_ : 0;
2319 template <
typename NodeIndexType,
typename ArcIndexType>
2322 NodeIndexType node)
const {
2323 if (node < left_nodes_) {
2325 right_nodes_ * (node + 1));
2331 template <
typename NodeIndexType,
typename ArcIndexType>
2334 NodeIndexType node, ArcIndexType from)
const {
2335 if (node < left_nodes_) {
2342 template <
typename NodeIndexType,
typename ArcIndexType>
2345 NodeIndexType node)
const {
2346 if (node < left_nodes_) {
2358 #undef DEFINE_RANGE_BASED_ARC_ITERATION
2359 #undef DEFINE_STL_ITERATOR_FUNCTIONS
2361 #endif // UTIL_GRAPH_GRAPH_H_