| 1513 | | ///\return An arc from \c s to \c t if there exists, |
| 1514 | | ///\ref INVALID otherwise. |
| 1515 | | Arc operator()(Node s, Node t) const |
| 1516 | | { |
| 1517 | | Arc a = _head[s]; |
| 1518 | | if (a == INVALID) return INVALID; |
| 1519 | | while (true) { |
| 1520 | | if (_g.target(a) == t) { |
| | 1512 | ///\param p The previous arc between \c s and \c t. It it is INVALID or |
| | 1513 | ///not given, the operator finds the first appropriate arc. |
| | 1514 | ///\return An arc from \c s to \c t after \c p or |
| | 1515 | ///\ref INVALID if there is no more. |
| | 1516 | /// |
| | 1517 | ///For example, you can count the number of arcs from \c u to \c v in the |
| | 1518 | ///following way. |
| | 1519 | ///\code |
| | 1520 | ///DynArcLookUp<ListDigraph> ae(g); |
| | 1521 | ///... |
| | 1522 | ///int n=0; |
| | 1523 | ///for(Arc e=ae(u,v);e!=INVALID;e=ae(u,v,e)) n++; |
| | 1524 | ///\endcode |
| | 1525 | /// |
| | 1526 | ///Finding the arcs take at most <em>O(</em>log<em>d)</em> |
| | 1527 | ///amortized time, specifically, the time complexity of the lookups |
| | 1528 | ///is equal to the optimal search tree implementation for the |
| | 1529 | ///current query distribution in a constant factor. |
| | 1530 | /// |
| | 1531 | ///\note This is a dynamic data structure, therefore the data |
| | 1532 | ///structure is updated after each graph alteration. However, |
| | 1533 | ///theoretically this data structure is faster than \c ArcLookUp |
| | 1534 | ///or AllEdgeLookup, but it often provides worse performance than |
| | 1535 | ///them. |
| | 1536 | /// |
| | 1537 | Arc operator()(Node s, Node t, Arc p = INVALID) const { |
| | 1538 | if (p == INVALID) { |
| | 1539 | Arc a = _head[s]; |
| | 1540 | if (a == INVALID) return INVALID; |
| | 1541 | Arc r = INVALID; |
| | 1542 | while (true) { |
| | 1543 | if (_g.target(a) < t) { |
| | 1544 | if (_right[a] == INVALID) { |
| | 1545 | const_cast<DynArcLookUp&>(*this).splay(a); |
| | 1546 | return r; |
| | 1547 | } else { |
| | 1548 | a = _right[a]; |
| | 1549 | } |
| | 1550 | } else { |
| | 1551 | if (_g.target(a) == t) { |
| | 1552 | r = a; |
| | 1553 | } |
| | 1554 | if (_left[a] == INVALID) { |
| | 1555 | const_cast<DynArcLookUp&>(*this).splay(a); |
| | 1556 | return r; |
| | 1557 | } else { |
| | 1558 | a = _left[a]; |
| | 1559 | } |
| | 1560 | } |
| | 1561 | } |
| | 1562 | } else { |
| | 1563 | Arc a = p; |
| | 1564 | if (_right[a] != INVALID) { |
| | 1565 | a = _right[a]; |
| | 1566 | while (_left[a] != INVALID) { |
| | 1567 | a = _left[a]; |
| | 1568 | } |
| 1539 | | } |
| 1540 | | |
| 1541 | | ///Find the first arc between two nodes. |
| 1542 | | |
| 1543 | | ///Find the first arc between two nodes in time |
| 1544 | | /// <em>O(</em>log<em>d)</em>, where <em>d</em> is the number of |
| 1545 | | /// outgoing arcs of \c s. |
| 1546 | | ///\param s The source node |
| 1547 | | ///\param t The target node |
| 1548 | | ///\return An arc from \c s to \c t if there exists, \ref INVALID |
| 1549 | | /// otherwise. |
| 1550 | | Arc findFirst(Node s, Node t) const |
| 1551 | | { |
| 1552 | | Arc a = _head[s]; |
| 1553 | | if (a == INVALID) return INVALID; |
| 1554 | | Arc r = INVALID; |
| 1555 | | while (true) { |
| 1556 | | if (_g.target(a) < t) { |
| 1557 | | if (_right[a] == INVALID) { |
| 1558 | | const_cast<DynArcLookUp&>(*this).splay(a); |
| 1559 | | return r; |
| 1560 | | } else { |
| 1561 | | a = _right[a]; |
| 1562 | | } |
| 1563 | | } else { |
| 1564 | | if (_g.target(a) == t) { |
| 1565 | | r = a; |
| 1566 | | } |
| 1567 | | if (_left[a] == INVALID) { |
| 1568 | | const_cast<DynArcLookUp&>(*this).splay(a); |
| 1569 | | return r; |
| 1570 | | } else { |
| 1571 | | a = _left[a]; |
| 1572 | | } |
| 1573 | | } |
| 1574 | | } |
| 1575 | | } |
| 1576 | | |
| 1577 | | ///Find the next arc between two nodes. |
| 1578 | | |
| 1579 | | ///Find the next arc between two nodes in time |
| 1580 | | /// <em>O(</em>log<em>d)</em>, where <em>d</em> is the number of |
| 1581 | | /// outgoing arcs of \c s. |
| 1582 | | ///\param s The source node |
| 1583 | | ///\param t The target node |
| 1584 | | ///\return An arc from \c s to \c t if there exists, \ref INVALID |
| 1585 | | /// otherwise. |
| 1586 | | |
| 1587 | | ///\note If \c e is not the result of the previous \c findFirst() |
| 1588 | | ///operation then the amorized time bound can not be guaranteed. |
| 1589 | | #ifdef DOXYGEN |
| 1590 | | Arc findNext(Node s, Node t, Arc a) const |
| 1591 | | #else |
| 1592 | | Arc findNext(Node, Node t, Arc a) const |
| 1593 | | #endif |
| 1594 | | { |
| 1595 | | if (_right[a] != INVALID) { |
| 1596 | | a = _right[a]; |
| 1597 | | while (_left[a] != INVALID) { |
| 1598 | | a = _left[a]; |
| 1599 | | } |
| 1600 | | const_cast<DynArcLookUp&>(*this).splay(a); |
| 1601 | | } else { |
| 1602 | | while (_parent[a] != INVALID && _right[_parent[a]] == a) { |
| 1603 | | a = _parent[a]; |
| 1604 | | } |
| 1605 | | if (_parent[a] == INVALID) { |
| 1606 | | return INVALID; |
| 1607 | | } else { |
| 1608 | | a = _parent[a]; |
| 1609 | | const_cast<DynArcLookUp&>(*this).splay(a); |
| 1610 | | } |
| 1611 | | } |
| 1612 | | if (_g.target(a) == t) return a; |
| 1613 | | else return INVALID; |