516 bool operator==(const Node i) const {return id==i.id;} |
516 bool operator==(const Node i) const {return id==i.id;} |
517 bool operator!=(const Node i) const {return id!=i.id;} |
517 bool operator!=(const Node i) const {return id!=i.id;} |
518 bool operator<(const Node i) const {return id<i.id;} |
518 bool operator<(const Node i) const {return id<i.id;} |
519 }; |
519 }; |
520 |
520 |
521 class Edge { |
521 class UEdge { |
522 friend class FullBpUGraphBase; |
522 friend class FullBpUGraphBase; |
523 protected: |
523 protected: |
524 int id; |
524 int id; |
525 |
525 |
526 Edge(int _id) { id = _id;} |
526 UEdge(int _id) { id = _id;} |
527 public: |
527 public: |
528 Edge() {} |
528 UEdge() {} |
529 Edge (Invalid) { id = -1; } |
529 UEdge (Invalid) { id = -1; } |
530 bool operator==(const Edge i) const {return id==i.id;} |
530 bool operator==(const UEdge i) const {return id==i.id;} |
531 bool operator!=(const Edge i) const {return id!=i.id;} |
531 bool operator!=(const UEdge i) const {return id!=i.id;} |
532 bool operator<(const Edge i) const {return id<i.id;} |
532 bool operator<(const UEdge i) const {return id<i.id;} |
533 }; |
533 }; |
534 |
534 |
535 void construct(int aNodeNum, int bNodeNum) { |
535 void construct(int aNodeNum, int bNodeNum) { |
536 _aNodeNum = aNodeNum; |
536 _aNodeNum = aNodeNum; |
537 _bNodeNum = bNodeNum; |
537 _bNodeNum = bNodeNum; |
566 if (node.id == -2) { |
566 if (node.id == -2) { |
567 node.id = 2 * _bNodeNum - 1; |
567 node.id = 2 * _bNodeNum - 1; |
568 } |
568 } |
569 } |
569 } |
570 |
570 |
571 void first(Edge& edge) const { |
571 void first(UEdge& edge) const { |
572 edge.id = _edgeNum - 1; |
572 edge.id = _edgeNum - 1; |
573 } |
573 } |
574 void next(Edge& edge) const { |
574 void next(UEdge& edge) const { |
575 --edge.id; |
575 --edge.id; |
576 } |
576 } |
577 |
577 |
578 void firstOut(Edge& edge, const Node& node) const { |
578 void firstFromANode(UEdge& edge, const Node& node) const { |
579 LEMON_ASSERT((node.id & 1) == 0, NodeSetError()); |
579 LEMON_ASSERT((node.id & 1) == 0, NodeSetError()); |
580 edge.id = (node.id >> 1) * _bNodeNum; |
580 edge.id = (node.id >> 1) * _bNodeNum; |
581 } |
581 } |
582 void nextOut(Edge& edge) const { |
582 void nextFromANode(UEdge& edge) const { |
583 ++(edge.id); |
583 ++(edge.id); |
584 if (edge.id % _bNodeNum == 0) edge.id = -1; |
584 if (edge.id % _bNodeNum == 0) edge.id = -1; |
585 } |
585 } |
586 |
586 |
587 void firstIn(Edge& edge, const Node& node) const { |
587 void firstFromBNode(UEdge& edge, const Node& node) const { |
588 LEMON_ASSERT((node.id & 1) == 1, NodeSetError()); |
588 LEMON_ASSERT((node.id & 1) == 1, NodeSetError()); |
589 edge.id = (node.id >> 1); |
589 edge.id = (node.id >> 1); |
590 } |
590 } |
591 void nextIn(Edge& edge) const { |
591 void nextFromBNode(UEdge& edge) const { |
592 edge.id += _bNodeNum; |
592 edge.id += _bNodeNum; |
593 if (edge.id >= _edgeNum) edge.id = -1; |
593 if (edge.id >= _edgeNum) edge.id = -1; |
594 } |
594 } |
595 |
595 |
596 static int id(const Node& node) { |
596 static int id(const Node& node) { |
602 int maxNodeId() const { |
602 int maxNodeId() const { |
603 return _aNodeNum > _bNodeNum ? |
603 return _aNodeNum > _bNodeNum ? |
604 _aNodeNum * 2 - 2 : _bNodeNum * 2 - 1; |
604 _aNodeNum * 2 - 2 : _bNodeNum * 2 - 1; |
605 } |
605 } |
606 |
606 |
607 static int id(const Edge& edge) { |
607 static int id(const UEdge& edge) { |
608 return edge.id; |
608 return edge.id; |
609 } |
609 } |
610 static Edge edgeFromId(int id) { |
610 static UEdge uEdgeFromId(int id) { |
611 return Edge(id); |
611 return UEdge(id); |
612 } |
612 } |
613 int maxEdgeId() const { |
613 int maxUEdgeId() const { |
614 return _edgeNum - 1; |
614 return _edgeNum - 1; |
615 } |
615 } |
616 |
616 |
617 static int aNodeId(const Node& node) { |
617 static int aNodeId(const Node& node) { |
618 return node.id >> 1; |
618 return node.id >> 1; |
632 } |
632 } |
633 int maxBNodeId() const { |
633 int maxBNodeId() const { |
634 return _bNodeNum; |
634 return _bNodeNum; |
635 } |
635 } |
636 |
636 |
637 Node aNode(const Edge& edge) const { |
637 Node aNode(const UEdge& edge) const { |
638 return Node((edge.id / _bNodeNum) << 1); |
638 return Node((edge.id / _bNodeNum) << 1); |
639 } |
639 } |
640 Node bNode(const Edge& edge) const { |
640 Node bNode(const UEdge& edge) const { |
641 return Node(((edge.id % _bNodeNum) << 1) + 1); |
641 return Node(((edge.id % _bNodeNum) << 1) + 1); |
642 } |
642 } |
643 |
643 |
644 static bool aNode(const Node& node) { |
644 static bool aNode(const Node& node) { |
645 return (node.id & 1) == 0; |
645 return (node.id & 1) == 0; |
661 int nodeNum() const { return _aNodeNum + _bNodeNum; } |
661 int nodeNum() const { return _aNodeNum + _bNodeNum; } |
662 int aNodeNum() const { return _aNodeNum; } |
662 int aNodeNum() const { return _aNodeNum; } |
663 int bNodeNum() const { return _bNodeNum; } |
663 int bNodeNum() const { return _bNodeNum; } |
664 |
664 |
665 typedef True EdgeNumTag; |
665 typedef True EdgeNumTag; |
666 int edgeNum() const { return _edgeNum; } |
666 int uEdgeNum() const { return _edgeNum; } |
667 |
667 |
668 }; |
668 }; |
669 |
669 |
670 |
670 |
671 typedef BpUGraphExtender< BpUGraphBaseExtender< |
671 typedef BpUGraphExtender<FullBpUGraphBase> ExtendedFullBpUGraphBase; |
672 FullBpUGraphBase> > ExtendedFullBpUGraphBase; |
|
673 |
672 |
674 |
673 |
675 /// \ingroup graphs |
674 /// \ingroup graphs |
676 /// |
675 /// |
677 /// \brief An undirected full bipartite graph class. |
676 /// \brief An undirected full bipartite graph class. |