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; |