deba@353: /* -*- mode: C++; indent-tabs-mode: nil; -*- deba@353: * deba@353: * This file is a part of LEMON, a generic C++ optimization library. deba@353: * alpar@1092: * Copyright (C) 2003-2013 deba@353: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@353: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@353: * deba@353: * Permission to use, modify and distribute this software is granted deba@353: * provided that this copyright notice appears in all copies. For deba@353: * precise terms see the accompanying LICENSE file. deba@353: * deba@353: * This software is provided "AS IS" with no warranty of any kind, deba@353: * express or implied, and with no claim as to its suitability for any deba@353: * purpose. deba@353: * deba@353: */ deba@353: deba@353: #ifndef LEMON_FULL_GRAPH_H deba@353: #define LEMON_FULL_GRAPH_H deba@353: deba@353: #include deba@353: #include deba@353: deba@353: ///\ingroup graphs deba@353: ///\file kpeter@735: ///\brief FullDigraph and FullGraph classes. kpeter@354: deba@353: namespace lemon { deba@353: deba@353: class FullDigraphBase { deba@353: public: deba@353: kpeter@617: typedef FullDigraphBase Digraph; deba@353: deba@353: class Node; deba@353: class Arc; deba@353: deba@353: protected: deba@353: deba@353: int _node_num; deba@353: int _arc_num; deba@353: deba@353: FullDigraphBase() {} deba@353: deba@353: void construct(int n) { _node_num = n; _arc_num = n * n; } deba@353: deba@353: public: deba@353: deba@353: typedef True NodeNumTag; deba@353: typedef True ArcNumTag; deba@353: deba@353: Node operator()(int ix) const { return Node(ix); } kpeter@778: static int index(const Node& node) { return node._id; } deba@353: deba@353: Arc arc(const Node& s, const Node& t) const { deba@353: return Arc(s._id * _node_num + t._id); deba@353: } deba@353: deba@353: int nodeNum() const { return _node_num; } deba@353: int arcNum() const { return _arc_num; } deba@353: deba@353: int maxNodeId() const { return _node_num - 1; } deba@353: int maxArcId() const { return _arc_num - 1; } deba@353: deba@353: Node source(Arc arc) const { return arc._id / _node_num; } deba@353: Node target(Arc arc) const { return arc._id % _node_num; } deba@353: deba@353: static int id(Node node) { return node._id; } deba@353: static int id(Arc arc) { return arc._id; } deba@353: deba@353: static Node nodeFromId(int id) { return Node(id);} deba@353: static Arc arcFromId(int id) { return Arc(id);} deba@353: deba@353: typedef True FindArcTag; deba@353: deba@353: Arc findArc(Node s, Node t, Arc prev = INVALID) const { kpeter@355: return prev == INVALID ? arc(s, t) : INVALID; deba@353: } deba@353: deba@353: class Node { deba@353: friend class FullDigraphBase; deba@353: deba@353: protected: deba@353: int _id; deba@353: Node(int id) : _id(id) {} deba@353: public: deba@353: Node() {} deba@353: Node (Invalid) : _id(-1) {} deba@353: bool operator==(const Node node) const {return _id == node._id;} deba@353: bool operator!=(const Node node) const {return _id != node._id;} deba@353: bool operator<(const Node node) const {return _id < node._id;} deba@353: }; deba@353: deba@353: class Arc { deba@353: friend class FullDigraphBase; deba@353: deba@353: protected: deba@353: int _id; // _node_num * source + target; deba@353: deba@353: Arc(int id) : _id(id) {} deba@353: deba@353: public: deba@353: Arc() { } deba@353: Arc (Invalid) { _id = -1; } deba@353: bool operator==(const Arc arc) const {return _id == arc._id;} deba@353: bool operator!=(const Arc arc) const {return _id != arc._id;} deba@353: bool operator<(const Arc arc) const {return _id < arc._id;} deba@353: }; deba@353: deba@353: void first(Node& node) const { deba@353: node._id = _node_num - 1; deba@353: } deba@353: deba@353: static void next(Node& node) { deba@353: --node._id; deba@353: } deba@353: deba@353: void first(Arc& arc) const { deba@353: arc._id = _arc_num - 1; deba@353: } deba@353: deba@353: static void next(Arc& arc) { deba@353: --arc._id; deba@353: } deba@353: deba@353: void firstOut(Arc& arc, const Node& node) const { deba@353: arc._id = (node._id + 1) * _node_num - 1; deba@353: } deba@353: deba@353: void nextOut(Arc& arc) const { deba@353: if (arc._id % _node_num == 0) arc._id = 0; deba@353: --arc._id; deba@353: } deba@353: deba@353: void firstIn(Arc& arc, const Node& node) const { deba@353: arc._id = _arc_num + node._id - _node_num; deba@353: } deba@353: deba@353: void nextIn(Arc& arc) const { deba@353: arc._id -= _node_num; deba@353: if (arc._id < 0) arc._id = -1; deba@353: } deba@353: deba@353: }; deba@353: deba@353: typedef DigraphExtender ExtendedFullDigraphBase; deba@353: deba@353: /// \ingroup graphs deba@353: /// kpeter@735: /// \brief A directed full graph class. deba@353: /// kpeter@735: /// FullDigraph is a simple and fast implmenetation of directed full kpeter@735: /// (complete) graphs. It contains an arc from each node to each node kpeter@735: /// (including a loop for each node), therefore the number of arcs kpeter@735: /// is the square of the number of nodes. kpeter@735: /// This class is completely static and it needs constant memory space. kpeter@735: /// Thus you can neither add nor delete nodes or arcs, however kpeter@735: /// the structure can be resized using resize(). deba@353: /// kpeter@735: /// This type fully conforms to the \ref concepts::Digraph "Digraph concept". kpeter@735: /// Most of its member functions and nested classes are documented kpeter@735: /// only in the concept class. kpeter@354: /// kpeter@787: /// This class provides constant time counting for nodes and arcs. kpeter@787: /// kpeter@735: /// \note FullDigraph and FullGraph classes are very similar, kpeter@354: /// but there are two differences. While this class conforms only kpeter@735: /// to the \ref concepts::Digraph "Digraph" concept, FullGraph kpeter@735: /// conforms to the \ref concepts::Graph "Graph" concept, kpeter@735: /// moreover FullGraph does not contain a loop for each kpeter@735: /// node as this class does. deba@353: /// deba@353: /// \sa FullGraph deba@353: class FullDigraph : public ExtendedFullDigraphBase { kpeter@617: typedef ExtendedFullDigraphBase Parent; kpeter@617: deba@353: public: deba@353: kpeter@735: /// \brief Default constructor. kpeter@735: /// kpeter@735: /// Default constructor. The number of nodes and arcs will be zero. deba@353: FullDigraph() { construct(0); } deba@353: deba@353: /// \brief Constructor deba@353: /// kpeter@354: /// Constructor. deba@353: /// \param n The number of the nodes. deba@353: FullDigraph(int n) { construct(n); } deba@353: kpeter@354: /// \brief Resizes the digraph deba@353: /// kpeter@735: /// This function resizes the digraph. It fully destroys and kpeter@735: /// rebuilds the structure, therefore the maps of the digraph will be kpeter@354: /// reallocated automatically and the previous values will be lost. deba@353: void resize(int n) { deba@353: Parent::notifier(Arc()).clear(); deba@353: Parent::notifier(Node()).clear(); deba@353: construct(n); deba@353: Parent::notifier(Node()).build(); deba@353: Parent::notifier(Arc()).build(); deba@353: } deba@353: deba@353: /// \brief Returns the node with the given index. deba@353: /// alpar@877: /// Returns the node with the given index. Since this structure is kpeter@735: /// completely static, the nodes can be indexed with integers from kpeter@735: /// the range [0..nodeNum()-1]. kpeter@787: /// The index of a node is the same as its ID. kpeter@354: /// \sa index() deba@353: Node operator()(int ix) const { return Parent::operator()(ix); } deba@353: kpeter@354: /// \brief Returns the index of the given node. deba@353: /// alpar@877: /// Returns the index of the given node. Since this structure is kpeter@735: /// completely static, the nodes can be indexed with integers from kpeter@735: /// the range [0..nodeNum()-1]. kpeter@787: /// The index of a node is the same as its ID. kpeter@735: /// \sa operator()() kpeter@778: static int index(const Node& node) { return Parent::index(node); } deba@353: kpeter@354: /// \brief Returns the arc connecting the given nodes. deba@353: /// kpeter@354: /// Returns the arc connecting the given nodes. kpeter@735: Arc arc(Node u, Node v) const { deba@353: return Parent::arc(u, v); deba@353: } deba@353: deba@353: /// \brief Number of nodes. deba@353: int nodeNum() const { return Parent::nodeNum(); } deba@353: /// \brief Number of arcs. deba@353: int arcNum() const { return Parent::arcNum(); } deba@353: }; deba@353: deba@353: deba@353: class FullGraphBase { deba@353: public: deba@353: deba@353: typedef FullGraphBase Graph; deba@353: deba@353: class Node; deba@353: class Arc; deba@353: class Edge; deba@353: deba@353: protected: deba@353: kpeter@617: int _node_num; kpeter@617: int _edge_num; kpeter@617: deba@353: FullGraphBase() {} deba@353: deba@353: void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; } deba@353: deba@353: int _uid(int e) const { deba@353: int u = e / _node_num; deba@353: int v = e % _node_num; deba@353: return u < v ? u : _node_num - 2 - u; deba@353: } deba@353: deba@353: int _vid(int e) const { deba@353: int u = e / _node_num; deba@353: int v = e % _node_num; deba@353: return u < v ? v : _node_num - 1 - v; deba@353: } deba@353: deba@353: void _uvid(int e, int& u, int& v) const { deba@353: u = e / _node_num; deba@353: v = e % _node_num; deba@353: if (u >= v) { deba@353: u = _node_num - 2 - u; deba@353: v = _node_num - 1 - v; deba@353: } deba@353: } deba@353: deba@353: void _stid(int a, int& s, int& t) const { deba@353: if ((a & 1) == 1) { deba@353: _uvid(a >> 1, s, t); deba@353: } else { deba@353: _uvid(a >> 1, t, s); deba@353: } deba@353: } deba@353: deba@353: int _eid(int u, int v) const { deba@353: if (u < (_node_num - 1) / 2) { deba@353: return u * _node_num + v; deba@353: } else { deba@353: return (_node_num - 1 - u) * _node_num - v - 1; deba@353: } deba@353: } deba@353: deba@353: public: deba@353: deba@353: Node operator()(int ix) const { return Node(ix); } kpeter@778: static int index(const Node& node) { return node._id; } deba@353: deba@353: Edge edge(const Node& u, const Node& v) const { deba@353: if (u._id < v._id) { deba@353: return Edge(_eid(u._id, v._id)); deba@353: } else if (u._id != v._id) { deba@353: return Edge(_eid(v._id, u._id)); deba@353: } else { deba@353: return INVALID; deba@353: } deba@353: } deba@353: deba@353: Arc arc(const Node& s, const Node& t) const { deba@353: if (s._id < t._id) { deba@353: return Arc((_eid(s._id, t._id) << 1) | 1); deba@353: } else if (s._id != t._id) { deba@353: return Arc(_eid(t._id, s._id) << 1); deba@353: } else { deba@353: return INVALID; deba@353: } deba@353: } deba@353: deba@353: typedef True NodeNumTag; kpeter@360: typedef True ArcNumTag; deba@353: typedef True EdgeNumTag; deba@353: deba@353: int nodeNum() const { return _node_num; } deba@353: int arcNum() const { return 2 * _edge_num; } deba@353: int edgeNum() const { return _edge_num; } deba@353: deba@353: static int id(Node node) { return node._id; } deba@353: static int id(Arc arc) { return arc._id; } deba@353: static int id(Edge edge) { return edge._id; } deba@353: deba@353: int maxNodeId() const { return _node_num-1; } deba@353: int maxArcId() const { return 2 * _edge_num-1; } deba@353: int maxEdgeId() const { return _edge_num-1; } deba@353: deba@353: static Node nodeFromId(int id) { return Node(id);} deba@353: static Arc arcFromId(int id) { return Arc(id);} deba@353: static Edge edgeFromId(int id) { return Edge(id);} deba@353: deba@353: Node u(Edge edge) const { deba@353: return Node(_uid(edge._id)); deba@353: } deba@353: deba@353: Node v(Edge edge) const { deba@353: return Node(_vid(edge._id)); deba@353: } deba@353: deba@353: Node source(Arc arc) const { deba@353: return Node((arc._id & 1) == 1 ? deba@353: _uid(arc._id >> 1) : _vid(arc._id >> 1)); deba@353: } deba@353: deba@353: Node target(Arc arc) const { deba@353: return Node((arc._id & 1) == 1 ? deba@353: _vid(arc._id >> 1) : _uid(arc._id >> 1)); deba@353: } deba@353: deba@353: typedef True FindEdgeTag; kpeter@360: typedef True FindArcTag; deba@353: deba@353: Edge findEdge(Node u, Node v, Edge prev = INVALID) const { deba@353: return prev != INVALID ? INVALID : edge(u, v); deba@353: } deba@353: deba@353: Arc findArc(Node s, Node t, Arc prev = INVALID) const { deba@353: return prev != INVALID ? INVALID : arc(s, t); deba@353: } deba@353: deba@353: class Node { deba@353: friend class FullGraphBase; deba@353: deba@353: protected: deba@353: int _id; deba@353: Node(int id) : _id(id) {} deba@353: public: deba@353: Node() {} deba@353: Node (Invalid) { _id = -1; } deba@353: bool operator==(const Node node) const {return _id == node._id;} deba@353: bool operator!=(const Node node) const {return _id != node._id;} deba@353: bool operator<(const Node node) const {return _id < node._id;} deba@353: }; deba@353: deba@353: class Edge { deba@353: friend class FullGraphBase; kpeter@354: friend class Arc; deba@353: deba@353: protected: deba@353: int _id; deba@353: deba@353: Edge(int id) : _id(id) {} deba@353: deba@353: public: deba@353: Edge() { } deba@353: Edge (Invalid) { _id = -1; } deba@353: deba@353: bool operator==(const Edge edge) const {return _id == edge._id;} deba@353: bool operator!=(const Edge edge) const {return _id != edge._id;} deba@353: bool operator<(const Edge edge) const {return _id < edge._id;} deba@353: }; deba@353: deba@353: class Arc { deba@353: friend class FullGraphBase; deba@353: deba@353: protected: deba@353: int _id; deba@353: deba@353: Arc(int id) : _id(id) {} deba@353: deba@353: public: deba@353: Arc() { } deba@353: Arc (Invalid) { _id = -1; } deba@353: deba@353: operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); } deba@353: deba@353: bool operator==(const Arc arc) const {return _id == arc._id;} deba@353: bool operator!=(const Arc arc) const {return _id != arc._id;} deba@353: bool operator<(const Arc arc) const {return _id < arc._id;} deba@353: }; deba@353: deba@353: static bool direction(Arc arc) { deba@353: return (arc._id & 1) == 1; deba@353: } deba@353: deba@353: static Arc direct(Edge edge, bool dir) { deba@353: return Arc((edge._id << 1) | (dir ? 1 : 0)); deba@353: } deba@353: deba@353: void first(Node& node) const { deba@353: node._id = _node_num - 1; deba@353: } deba@353: deba@353: static void next(Node& node) { deba@353: --node._id; deba@353: } deba@353: deba@353: void first(Arc& arc) const { deba@353: arc._id = (_edge_num << 1) - 1; deba@353: } deba@353: deba@353: static void next(Arc& arc) { deba@353: --arc._id; deba@353: } deba@353: deba@353: void first(Edge& edge) const { deba@353: edge._id = _edge_num - 1; deba@353: } deba@353: deba@353: static void next(Edge& edge) { deba@353: --edge._id; deba@353: } deba@353: deba@353: void firstOut(Arc& arc, const Node& node) const { deba@353: int s = node._id, t = _node_num - 1; deba@353: if (s < t) { deba@353: arc._id = (_eid(s, t) << 1) | 1; deba@353: } else { deba@353: --t; deba@353: arc._id = (t != -1 ? (_eid(t, s) << 1) : -1); deba@353: } deba@353: } deba@353: deba@353: void nextOut(Arc& arc) const { deba@353: int s, t; deba@353: _stid(arc._id, s, t); deba@353: --t; deba@353: if (s < t) { deba@353: arc._id = (_eid(s, t) << 1) | 1; deba@353: } else { deba@353: if (s == t) --t; deba@353: arc._id = (t != -1 ? (_eid(t, s) << 1) : -1); deba@353: } deba@353: } deba@353: deba@353: void firstIn(Arc& arc, const Node& node) const { deba@353: int s = _node_num - 1, t = node._id; deba@353: if (s > t) { deba@353: arc._id = (_eid(t, s) << 1); deba@353: } else { deba@353: --s; deba@353: arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1); deba@353: } deba@353: } deba@353: deba@353: void nextIn(Arc& arc) const { deba@353: int s, t; deba@353: _stid(arc._id, s, t); deba@353: --s; deba@353: if (s > t) { deba@353: arc._id = (_eid(t, s) << 1); deba@353: } else { deba@353: if (s == t) --s; deba@353: arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1); deba@353: } deba@353: } deba@353: deba@353: void firstInc(Edge& edge, bool& dir, const Node& node) const { deba@353: int u = node._id, v = _node_num - 1; deba@353: if (u < v) { deba@353: edge._id = _eid(u, v); deba@353: dir = true; deba@353: } else { deba@353: --v; deba@353: edge._id = (v != -1 ? _eid(v, u) : -1); deba@353: dir = false; deba@353: } deba@353: } deba@353: deba@353: void nextInc(Edge& edge, bool& dir) const { deba@353: int u, v; deba@353: if (dir) { deba@353: _uvid(edge._id, u, v); deba@353: --v; deba@353: if (u < v) { deba@353: edge._id = _eid(u, v); deba@353: } else { deba@353: --v; deba@353: edge._id = (v != -1 ? _eid(v, u) : -1); deba@353: dir = false; deba@353: } deba@353: } else { deba@353: _uvid(edge._id, v, u); deba@353: --v; deba@353: edge._id = (v != -1 ? _eid(v, u) : -1); deba@353: } deba@353: } deba@353: deba@353: }; deba@353: deba@353: typedef GraphExtender ExtendedFullGraphBase; deba@353: deba@353: /// \ingroup graphs deba@353: /// deba@353: /// \brief An undirected full graph class. deba@353: /// kpeter@735: /// FullGraph is a simple and fast implmenetation of undirected full kpeter@735: /// (complete) graphs. It contains an edge between every distinct pair kpeter@735: /// of nodes, therefore the number of edges is n(n-1)/2. kpeter@735: /// This class is completely static and it needs constant memory space. kpeter@735: /// Thus you can neither add nor delete nodes or edges, however kpeter@735: /// the structure can be resized using resize(). deba@353: /// kpeter@735: /// This type fully conforms to the \ref concepts::Graph "Graph concept". kpeter@735: /// Most of its member functions and nested classes are documented kpeter@735: /// only in the concept class. deba@353: /// kpeter@787: /// This class provides constant time counting for nodes, edges and arcs. kpeter@787: /// kpeter@735: /// \note FullDigraph and FullGraph classes are very similar, kpeter@735: /// but there are two differences. While FullDigraph kpeter@354: /// conforms only to the \ref concepts::Digraph "Digraph" concept, kpeter@354: /// this class conforms to the \ref concepts::Graph "Graph" concept, kpeter@735: /// moreover this class does not contain a loop for each kpeter@735: /// node as FullDigraph does. deba@353: /// deba@353: /// \sa FullDigraph deba@353: class FullGraph : public ExtendedFullGraphBase { kpeter@617: typedef ExtendedFullGraphBase Parent; kpeter@617: deba@353: public: deba@353: kpeter@735: /// \brief Default constructor. kpeter@735: /// kpeter@735: /// Default constructor. The number of nodes and edges will be zero. deba@353: FullGraph() { construct(0); } deba@353: deba@353: /// \brief Constructor deba@353: /// kpeter@354: /// Constructor. deba@353: /// \param n The number of the nodes. deba@353: FullGraph(int n) { construct(n); } deba@353: kpeter@354: /// \brief Resizes the graph deba@353: /// kpeter@735: /// This function resizes the graph. It fully destroys and kpeter@735: /// rebuilds the structure, therefore the maps of the graph will be kpeter@354: /// reallocated automatically and the previous values will be lost. deba@353: void resize(int n) { deba@353: Parent::notifier(Arc()).clear(); deba@353: Parent::notifier(Edge()).clear(); deba@353: Parent::notifier(Node()).clear(); deba@353: construct(n); deba@353: Parent::notifier(Node()).build(); deba@353: Parent::notifier(Edge()).build(); deba@353: Parent::notifier(Arc()).build(); deba@353: } deba@353: deba@353: /// \brief Returns the node with the given index. deba@353: /// alpar@877: /// Returns the node with the given index. Since this structure is kpeter@735: /// completely static, the nodes can be indexed with integers from kpeter@735: /// the range [0..nodeNum()-1]. kpeter@787: /// The index of a node is the same as its ID. kpeter@354: /// \sa index() deba@353: Node operator()(int ix) const { return Parent::operator()(ix); } deba@353: kpeter@354: /// \brief Returns the index of the given node. deba@353: /// alpar@877: /// Returns the index of the given node. Since this structure is kpeter@735: /// completely static, the nodes can be indexed with integers from kpeter@735: /// the range [0..nodeNum()-1]. kpeter@787: /// The index of a node is the same as its ID. kpeter@735: /// \sa operator()() kpeter@778: static int index(const Node& node) { return Parent::index(node); } deba@353: kpeter@354: /// \brief Returns the arc connecting the given nodes. deba@353: /// kpeter@354: /// Returns the arc connecting the given nodes. kpeter@735: Arc arc(Node s, Node t) const { deba@353: return Parent::arc(s, t); deba@353: } deba@353: kpeter@735: /// \brief Returns the edge connecting the given nodes. deba@353: /// kpeter@735: /// Returns the edge connecting the given nodes. kpeter@735: Edge edge(Node u, Node v) const { deba@353: return Parent::edge(u, v); deba@353: } kpeter@354: kpeter@354: /// \brief Number of nodes. kpeter@354: int nodeNum() const { return Parent::nodeNum(); } kpeter@354: /// \brief Number of arcs. kpeter@354: int arcNum() const { return Parent::arcNum(); } kpeter@354: /// \brief Number of edges. kpeter@354: int edgeNum() const { return Parent::edgeNum(); } kpeter@354: deba@353: }; deba@353: deba@1020: class FullBpGraphBase { deba@1020: deba@1020: protected: deba@1020: deba@1020: int _red_num, _blue_num; deba@1020: int _node_num, _edge_num; deba@1020: deba@1020: public: deba@1020: deba@1020: typedef FullBpGraphBase Graph; deba@1020: deba@1020: class Node; deba@1020: class Arc; deba@1020: class Edge; deba@1020: deba@1020: class Node { deba@1020: friend class FullBpGraphBase; deba@1020: protected: deba@1020: deba@1020: int _id; deba@1020: explicit Node(int id) { _id = id;} deba@1020: deba@1020: public: deba@1020: Node() {} deba@1020: Node (Invalid) { _id = -1; } deba@1020: bool operator==(const Node& node) const {return _id == node._id;} deba@1020: bool operator!=(const Node& node) const {return _id != node._id;} deba@1020: bool operator<(const Node& node) const {return _id < node._id;} deba@1020: }; deba@1020: deba@1025: class RedNode : public Node { deba@1025: friend class FullBpGraphBase; deba@1025: protected: deba@1025: deba@1025: explicit RedNode(int pid) : Node(pid) {} deba@1025: deba@1025: public: deba@1025: RedNode() {} deba@1025: RedNode(const RedNode& node) : Node(node) {} deba@1025: RedNode(Invalid) : Node(INVALID){} deba@1025: }; deba@1025: deba@1025: class BlueNode : public Node { deba@1025: friend class FullBpGraphBase; deba@1025: protected: deba@1025: deba@1025: explicit BlueNode(int pid) : Node(pid) {} deba@1025: deba@1025: public: deba@1025: BlueNode() {} deba@1025: BlueNode(const BlueNode& node) : Node(node) {} deba@1025: BlueNode(Invalid) : Node(INVALID){} deba@1025: }; deba@1025: deba@1020: class Edge { deba@1020: friend class FullBpGraphBase; deba@1020: protected: deba@1020: deba@1020: int _id; deba@1020: explicit Edge(int id) { _id = id;} deba@1020: deba@1020: public: deba@1020: Edge() {} deba@1020: Edge (Invalid) { _id = -1; } deba@1020: bool operator==(const Edge& arc) const {return _id == arc._id;} deba@1020: bool operator!=(const Edge& arc) const {return _id != arc._id;} deba@1020: bool operator<(const Edge& arc) const {return _id < arc._id;} deba@1020: }; deba@1020: deba@1020: class Arc { deba@1020: friend class FullBpGraphBase; deba@1020: protected: deba@1020: deba@1020: int _id; deba@1020: explicit Arc(int id) { _id = id;} deba@1020: deba@1020: public: deba@1020: operator Edge() const { deba@1020: return _id != -1 ? edgeFromId(_id / 2) : INVALID; deba@1020: } deba@1020: deba@1020: Arc() {} deba@1020: Arc (Invalid) { _id = -1; } deba@1020: bool operator==(const Arc& arc) const {return _id == arc._id;} deba@1020: bool operator!=(const Arc& arc) const {return _id != arc._id;} deba@1020: bool operator<(const Arc& arc) const {return _id < arc._id;} deba@1020: }; deba@1020: deba@1020: deba@1020: protected: deba@1020: deba@1020: FullBpGraphBase() deba@1020: : _red_num(0), _blue_num(0), _node_num(0), _edge_num(0) {} deba@1020: deba@1020: void construct(int redNum, int blueNum) { deba@1020: _red_num = redNum; _blue_num = blueNum; deba@1020: _node_num = redNum + blueNum; _edge_num = redNum * blueNum; deba@1020: } deba@1020: deba@1020: public: deba@1020: deba@1020: typedef True NodeNumTag; deba@1020: typedef True EdgeNumTag; deba@1020: typedef True ArcNumTag; deba@1020: deba@1020: int nodeNum() const { return _node_num; } deba@1020: int redNum() const { return _red_num; } deba@1020: int blueNum() const { return _blue_num; } deba@1020: int edgeNum() const { return _edge_num; } deba@1020: int arcNum() const { return 2 * _edge_num; } deba@1020: deba@1020: int maxNodeId() const { return _node_num - 1; } deba@1020: int maxRedId() const { return _red_num - 1; } deba@1020: int maxBlueId() const { return _blue_num - 1; } deba@1020: int maxEdgeId() const { return _edge_num - 1; } deba@1020: int maxArcId() const { return 2 * _edge_num - 1; } deba@1020: deba@1020: bool red(Node n) const { return n._id < _red_num; } deba@1020: bool blue(Node n) const { return n._id >= _red_num; } deba@1020: deba@1025: static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); } deba@1025: static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); } deba@1025: deba@1020: Node source(Arc a) const { deba@1020: if (a._id & 1) { deba@1020: return Node((a._id >> 1) % _red_num); deba@1020: } else { deba@1020: return Node((a._id >> 1) / _red_num + _red_num); deba@1020: } deba@1020: } deba@1020: Node target(Arc a) const { deba@1020: if (a._id & 1) { deba@1020: return Node((a._id >> 1) / _red_num + _red_num); deba@1020: } else { deba@1020: return Node((a._id >> 1) % _red_num); deba@1020: } deba@1020: } deba@1020: deba@1025: RedNode redNode(Edge e) const { deba@1025: return RedNode(e._id % _red_num); deba@1020: } deba@1025: BlueNode blueNode(Edge e) const { deba@1025: return BlueNode(e._id / _red_num + _red_num); deba@1020: } deba@1020: deba@1020: static bool direction(Arc a) { deba@1020: return (a._id & 1) == 1; deba@1020: } deba@1020: deba@1020: static Arc direct(Edge e, bool d) { deba@1020: return Arc(e._id * 2 + (d ? 1 : 0)); deba@1020: } deba@1020: deba@1020: void first(Node& node) const { deba@1020: node._id = _node_num - 1; deba@1020: } deba@1020: deba@1020: static void next(Node& node) { deba@1020: --node._id; deba@1020: } deba@1020: deba@1025: void first(RedNode& node) const { deba@1020: node._id = _red_num - 1; deba@1020: } deba@1020: deba@1025: static void next(RedNode& node) { deba@1020: --node._id; deba@1020: } deba@1020: deba@1025: void first(BlueNode& node) const { deba@1020: if (_red_num == _node_num) node._id = -1; deba@1020: else node._id = _node_num - 1; deba@1020: } deba@1020: deba@1025: void next(BlueNode& node) const { deba@1020: if (node._id == _red_num) node._id = -1; deba@1020: else --node._id; deba@1020: } deba@1020: deba@1020: void first(Arc& arc) const { deba@1020: arc._id = 2 * _edge_num - 1; deba@1020: } deba@1020: deba@1020: static void next(Arc& arc) { deba@1020: --arc._id; deba@1020: } deba@1020: deba@1020: void first(Edge& arc) const { deba@1020: arc._id = _edge_num - 1; deba@1020: } deba@1020: deba@1020: static void next(Edge& arc) { deba@1020: --arc._id; deba@1020: } deba@1020: deba@1020: void firstOut(Arc &a, const Node& v) const { deba@1020: if (v._id < _red_num) { deba@1020: a._id = 2 * (v._id + _red_num * (_blue_num - 1)) + 1; deba@1020: } else { deba@1020: a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num)); deba@1020: } deba@1020: } deba@1020: void nextOut(Arc &a) const { deba@1020: if (a._id & 1) { deba@1020: a._id -= 2 * _red_num; deba@1020: if (a._id < 0) a._id = -1; deba@1020: } else { deba@1020: if (a._id % (2 * _red_num) == 0) a._id = -1; deba@1020: else a._id -= 2; deba@1020: } deba@1020: } deba@1020: deba@1020: void firstIn(Arc &a, const Node& v) const { deba@1020: if (v._id < _red_num) { deba@1020: a._id = 2 * (v._id + _red_num * (_blue_num - 1)); deba@1020: } else { deba@1020: a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num)) + 1; deba@1020: } deba@1020: } deba@1020: void nextIn(Arc &a) const { deba@1020: if (a._id & 1) { deba@1020: if (a._id % (2 * _red_num) == 1) a._id = -1; deba@1020: else a._id -= 2; deba@1020: } else { deba@1020: a._id -= 2 * _red_num; deba@1020: if (a._id < 0) a._id = -1; deba@1020: } deba@1020: } deba@1020: deba@1020: void firstInc(Edge &e, bool& d, const Node& v) const { deba@1020: if (v._id < _red_num) { deba@1020: d = true; deba@1020: e._id = v._id + _red_num * (_blue_num - 1); deba@1020: } else { deba@1020: d = false; deba@1020: e._id = _red_num - 1 + _red_num * (v._id - _red_num); deba@1020: } deba@1020: } deba@1020: void nextInc(Edge &e, bool& d) const { deba@1020: if (d) { deba@1020: e._id -= _red_num; deba@1020: if (e._id < 0) e._id = -1; deba@1020: } else { deba@1020: if (e._id % _red_num == 0) e._id = -1; deba@1020: else --e._id; deba@1020: } deba@1020: } deba@1020: deba@1025: static int id(const Node& v) { return v._id; } deba@1025: int id(const RedNode& v) const { return v._id; } deba@1025: int id(const BlueNode& v) const { return v._id - _red_num; } deba@1020: static int id(Arc e) { return e._id; } deba@1020: static int id(Edge e) { return e._id; } alpar@1092: deba@1020: static Node nodeFromId(int id) { return Node(id);} deba@1020: static Arc arcFromId(int id) { return Arc(id);} deba@1020: static Edge edgeFromId(int id) { return Edge(id);} deba@1020: deba@1020: bool valid(Node n) const { deba@1020: return n._id >= 0 && n._id < _node_num; deba@1020: } deba@1020: bool valid(Arc a) const { deba@1020: return a._id >= 0 && a._id < 2 * _edge_num; deba@1020: } deba@1020: bool valid(Edge e) const { deba@1020: return e._id >= 0 && e._id < _edge_num; deba@1020: } deba@1020: deba@1025: RedNode redNode(int index) const { deba@1025: return RedNode(index); deba@1020: } deba@1020: deba@1025: int index(RedNode n) const { deba@1020: return n._id; deba@1020: } deba@1020: deba@1025: BlueNode blueNode(int index) const { deba@1025: return BlueNode(index + _red_num); deba@1020: } deba@1020: deba@1025: int index(BlueNode n) const { deba@1020: return n._id - _red_num; deba@1020: } alpar@1092: deba@1020: void clear() { deba@1020: _red_num = 0; _blue_num = 0; deba@1020: _node_num = 0; _edge_num = 0; deba@1020: } deba@1020: alpar@1092: Edge edge(const Node& u, const Node& v) const { deba@1020: if (u._id < _red_num) { deba@1020: if (v._id < _red_num) { deba@1020: return Edge(-1); deba@1020: } else { deba@1020: return Edge(u._id + _red_num * (v._id - _red_num)); deba@1020: } deba@1020: } else { deba@1020: if (v._id < _red_num) { deba@1020: return Edge(v._id + _red_num * (u._id - _red_num)); deba@1020: } else { deba@1020: return Edge(-1); deba@1020: } deba@1020: } deba@1020: } deba@1020: alpar@1092: Arc arc(const Node& u, const Node& v) const { deba@1020: if (u._id < _red_num) { deba@1020: if (v._id < _red_num) { deba@1020: return Arc(-1); deba@1020: } else { deba@1020: return Arc(2 * (u._id + _red_num * (v._id - _red_num)) + 1); deba@1020: } deba@1020: } else { deba@1020: if (v._id < _red_num) { deba@1020: return Arc(2 * (v._id + _red_num * (u._id - _red_num))); deba@1020: } else { deba@1020: return Arc(-1); deba@1020: } deba@1020: } deba@1020: } deba@1020: deba@1020: typedef True FindEdgeTag; deba@1020: typedef True FindArcTag; deba@1020: deba@1020: Edge findEdge(Node u, Node v, Edge prev = INVALID) const { deba@1020: return prev != INVALID ? INVALID : edge(u, v); deba@1020: } deba@1020: deba@1020: Arc findArc(Node s, Node t, Arc prev = INVALID) const { deba@1020: return prev != INVALID ? INVALID : arc(s, t); deba@1020: } deba@1020: deba@1020: }; deba@1020: deba@1020: typedef BpGraphExtender ExtendedFullBpGraphBase; deba@1020: deba@1020: /// \ingroup graphs deba@1020: /// deba@1020: /// \brief An undirected full bipartite graph class. deba@1020: /// deba@1020: /// FullBpGraph is a simple and fast implmenetation of undirected deba@1020: /// full bipartite graphs. It contains an edge between every deba@1020: /// red-blue pairs of nodes, therefore the number of edges is deba@1020: /// nr*nb. This class is completely static and it needs deba@1020: /// constant memory space. Thus you can neither add nor delete deba@1020: /// nodes or edges, however the structure can be resized using deba@1020: /// resize(). deba@1020: /// deba@1020: /// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept". deba@1020: /// Most of its member functions and nested classes are documented deba@1020: /// only in the concept class. deba@1020: /// deba@1020: /// This class provides constant time counting for nodes, edges and arcs. deba@1020: /// deba@1020: /// \sa FullGraph deba@1020: class FullBpGraph : public ExtendedFullBpGraphBase { deba@1020: public: deba@1020: deba@1020: typedef ExtendedFullBpGraphBase Parent; deba@1020: deba@1020: /// \brief Default constructor. deba@1020: /// deba@1020: /// Default constructor. The number of nodes and edges will be zero. deba@1020: FullBpGraph() { construct(0, 0); } deba@1020: deba@1020: /// \brief Constructor deba@1020: /// deba@1020: /// Constructor. deba@1020: /// \param redNum The number of the red nodes. deba@1020: /// \param blueNum The number of the blue nodes. deba@1020: FullBpGraph(int redNum, int blueNum) { construct(redNum, blueNum); } deba@1020: deba@1020: /// \brief Resizes the graph deba@1020: /// deba@1020: /// This function resizes the graph. It fully destroys and deba@1020: /// rebuilds the structure, therefore the maps of the graph will be deba@1020: /// reallocated automatically and the previous values will be lost. deba@1020: void resize(int redNum, int blueNum) { deba@1020: Parent::notifier(Arc()).clear(); deba@1020: Parent::notifier(Edge()).clear(); deba@1020: Parent::notifier(Node()).clear(); deba@1020: Parent::notifier(BlueNode()).clear(); deba@1020: Parent::notifier(RedNode()).clear(); deba@1020: construct(redNum, blueNum); deba@1020: Parent::notifier(RedNode()).build(); deba@1020: Parent::notifier(BlueNode()).build(); deba@1020: Parent::notifier(Node()).build(); deba@1020: Parent::notifier(Edge()).build(); deba@1020: Parent::notifier(Arc()).build(); deba@1020: } deba@1020: deba@1024: using Parent::redNode; deba@1024: using Parent::blueNode; deba@1024: deba@1020: /// \brief Returns the red node with the given index. deba@1020: /// deba@1020: /// Returns the red node with the given index. Since this deba@1020: /// structure is completely static, the red nodes can be indexed deba@1020: /// with integers from the range [0..redNum()-1]. deba@1020: /// \sa redIndex() deba@1025: RedNode redNode(int index) const { return Parent::redNode(index); } deba@1020: deba@1020: /// \brief Returns the index of the given red node. deba@1020: /// deba@1020: /// Returns the index of the given red node. Since this structure deba@1020: /// is completely static, the red nodes can be indexed with deba@1020: /// integers from the range [0..redNum()-1]. deba@1020: /// deba@1020: /// \sa operator()() deba@1025: int index(RedNode node) const { return Parent::index(node); } deba@1020: deba@1020: /// \brief Returns the blue node with the given index. deba@1020: /// deba@1020: /// Returns the blue node with the given index. Since this deba@1020: /// structure is completely static, the blue nodes can be indexed deba@1020: /// with integers from the range [0..blueNum()-1]. deba@1020: /// \sa blueIndex() deba@1025: BlueNode blueNode(int index) const { return Parent::blueNode(index); } deba@1020: deba@1020: /// \brief Returns the index of the given blue node. deba@1020: /// deba@1020: /// Returns the index of the given blue node. Since this structure deba@1020: /// is completely static, the blue nodes can be indexed with deba@1020: /// integers from the range [0..blueNum()-1]. deba@1020: /// deba@1020: /// \sa operator()() deba@1025: int index(BlueNode node) const { return Parent::index(node); } deba@1020: deba@1020: /// \brief Returns the edge which connects the given nodes. deba@1020: /// deba@1020: /// Returns the edge which connects the given nodes. deba@1020: Edge edge(const Node& u, const Node& v) const { deba@1020: return Parent::edge(u, v); deba@1020: } deba@1020: deba@1020: /// \brief Returns the arc which connects the given nodes. deba@1020: /// deba@1020: /// Returns the arc which connects the given nodes. deba@1020: Arc arc(const Node& u, const Node& v) const { deba@1020: return Parent::arc(u, v); deba@1020: } deba@1020: deba@1020: /// \brief Number of nodes. deba@1020: int nodeNum() const { return Parent::nodeNum(); } deba@1020: /// \brief Number of red nodes. deba@1020: int redNum() const { return Parent::redNum(); } deba@1020: /// \brief Number of blue nodes. deba@1020: int blueNum() const { return Parent::blueNum(); } deba@1020: /// \brief Number of arcs. deba@1020: int arcNum() const { return Parent::arcNum(); } deba@1020: /// \brief Number of edges. deba@1020: int edgeNum() const { return Parent::edgeNum(); } deba@1020: }; deba@1020: deba@353: deba@353: } //namespace lemon deba@353: deba@353: deba@353: #endif //LEMON_FULL_GRAPH_H