diff -r fd82adfbe905 -r 22099ef840d7 lemon/full_graph.h --- a/lemon/full_graph.h Mon Nov 21 12:07:05 2005 +0000 +++ b/lemon/full_graph.h Mon Nov 21 17:48:00 2005 +0000 @@ -402,6 +402,196 @@ UndirFullGraph(int n) { construct(n); } }; + + class FullUndirBipartiteGraphBase { + protected: + + int _upperNodeNum; + int _lowerNodeNum; + + int _edgeNum; + + public: + + class NodeSetError : public LogicError { + virtual const char* exceptionName() const { + return "lemon::FullUndirBipartiteGraph::NodeSetError"; + } + }; + + class Node { + friend class FullUndirBipartiteGraphBase; + protected: + int id; + + Node(int _id) : id(_id) {} + public: + Node() {} + Node(Invalid) { id = -1; } + bool operator==(const Node i) const {return id==i.id;} + bool operator!=(const Node i) const {return id!=i.id;} + bool operator<(const Node i) const {return id 0) { + node.id = 2 * _upperNodeNum - 2; + } else { + node.id = 2 * _lowerNodeNum - 1; + } + } + void next(Node& node) const { + node.id -= 2; + if (node.id == -2) { + node.id = 2 * _lowerNodeNum - 1; + } + } + + void first(Edge& edge) const { + edge.id = _edgeNum - 1; + } + void next(Edge& edge) const { + --edge.id; + } + + void firstDown(Edge& edge, const Node& node) const { + LEMON_ASSERT((node.id & 1) == 0, NodeSetError()); + edge.id = (node.id >> 1) * _lowerNodeNum; + } + void nextDown(Edge& edge) const { + ++(edge.id); + if (edge.id % _lowerNodeNum == 0) edge.id = -1; + } + + void firstUp(Edge& edge, const Node& node) const { + LEMON_ASSERT((node.id & 1) == 1, NodeSetError()); + edge.id = (node.id >> 1); + } + void nextUp(Edge& edge) const { + edge.id += _lowerNodeNum; + if (edge.id >= _edgeNum) edge.id = -1; + } + + static int id(const Node& node) { + return node.id; + } + static Node nodeFromId(int id) { + return Node(id); + } + int maxNodeId() const { + return _upperNodeNum > _lowerNodeNum ? + _upperNodeNum * 2 - 2 : _lowerNodeNum * 2 - 1; + } + + static int id(const Edge& edge) { + return edge.id; + } + static Edge edgeFromId(int id) { + return Edge(id); + } + int maxEdgeId() const { + return _edgeNum - 1; + } + + static int upperId(const Node& node) { + return node.id >> 1; + } + static Node fromUpperId(int id, Node) { + return Node(id << 1); + } + int maxUpperId() const { + return _upperNodeNum; + } + + static int lowerId(const Node& node) { + return node.id >> 1; + } + static Node fromLowerId(int id) { + return Node((id << 1) + 1); + } + int maxLowerId() const { + return _lowerNodeNum; + } + + Node upperNode(const Edge& edge) const { + return Node((edge.id / _lowerNodeNum) << 1); + } + Node lowerNode(const Edge& edge) const { + return Node(((edge.id % _lowerNodeNum) << 1) + 1); + } + + static bool upper(const Node& node) { + return (node.id & 1) == 0; + } + + static bool lower(const Node& node) { + return (node.id & 1) == 1; + } + + static Node upperNode(int index) { + return Node(index << 1); + } + + static Node lowerNode(int index) { + return Node((index << 1) + 1); + } + + }; + + + typedef MappableUndirBipartiteGraphExtender< + IterableUndirBipartiteGraphExtender< + AlterableUndirBipartiteGraphExtender< + UndirBipartiteGraphExtender < + FullUndirBipartiteGraphBase> > > > + ExtendedFullUndirBipartiteGraphBase; + + + class FullUndirBipartiteGraph : + public ExtendedFullUndirBipartiteGraphBase { + public: + typedef ExtendedFullUndirBipartiteGraphBase Parent; + FullUndirBipartiteGraph(int upperNodeNum, int lowerNodeNum) { + Parent::construct(upperNodeNum, lowerNodeNum); + } + }; + } //namespace lemon