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