Index: lemon/full_graph.h
===================================================================
--- lemon/full_graph.h	(revision 2162)
+++ lemon/full_graph.h	(revision 2223)
@@ -36,7 +36,4 @@
 namespace lemon {
 
-  /// \brief Base of the FullGrpah.
-  ///
-  /// Base of the FullGrpah.
   class FullGraphBase {
     int _nodeNum;
@@ -49,45 +46,26 @@
     class Edge;
 
+  protected:
+
+    FullGraphBase() {}
+
+    void construct(int n) { _nodeNum = n; _edgeNum = n * n; }
+
   public:
-
-    FullGraphBase() {}
-
-
-    ///Creates a full graph with \c n nodes.
-    void construct(int n) { _nodeNum = n; _edgeNum = n * n; }
     
     typedef True NodeNumTag;
     typedef True EdgeNumTag;
 
-    /// \brief Returns the node with the given index.
-    ///
-    /// Returns the node with the given index. Because it is a
-    /// static size graph the node's of the graph can be indiced
-    /// by the range from 0 to \e nodeNum()-1 and the index of
-    /// the node can accessed by the \e index() member.
     Node operator()(int index) const { return Node(index); }
-
-    /// \brief Returns the index of the node.
-    ///
-    /// Returns the index of the node. Because it is a
-    /// static size graph the node's of the graph can be indiced
-    /// by the range from 0 to \e nodeNum()-1 and the index of
-    /// the node can accessed by the \e index() member.
     int index(const Node& node) const { return node.id; }
 
-    ///Number of nodes.
+    Edge edge(const Node& u, const Node& v) const { 
+      return Edge(*this, u.id, v.id); 
+    }
+
     int nodeNum() const { return _nodeNum; }
-    ///Number of edges.
     int edgeNum() const { return _edgeNum; }
 
-    /// Maximum node ID.
-    
-    /// Maximum node ID.
-    ///\sa id(Node)
     int maxNodeId() const { return _nodeNum-1; }
-    /// Maximum edge ID.
-    
-    /// Maximum edge ID.
-    ///\sa id(Edge)
     int maxEdgeId() const { return _edgeNum-1; }
 
@@ -96,22 +74,5 @@
 
 
-    /// Node ID.
-    
-    /// The ID of a valid Node is a nonnegative integer not greater than
-    /// \ref maxNodeId(). The range of the ID's is not surely continuous
-    /// and the greatest node ID can be actually less then \ref maxNodeId().
-    ///
-    /// The ID of the \ref INVALID node is -1.
-    ///\return The ID of the node \c v. 
-
     static int id(Node v) { return v.id; }
-    /// Edge ID.
-    
-    /// The ID of a valid Edge is a nonnegative integer not greater than
-    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
-    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
-    ///
-    /// The ID of the \ref INVALID edge is -1.
-    ///\return The ID of the edge \c e. 
     static int id(Edge e) { return e.id; }
 
@@ -122,12 +83,4 @@
     typedef True FindEdgeTag;
 
-    /// Finds an edge between two nodes.
-    
-    /// Finds an edge from node \c u to node \c v.
-    ///
-    /// If \c prev is \ref INVALID (this is the default value), then
-    /// It finds the first edge from \c u to \c v. Otherwise it looks for
-    /// the next edge from \c u to \c v after \c prev.
-    /// \return The found edge or INVALID if there is no such an edge.
     Edge findEdge(Node u,Node v, Edge prev = INVALID) const {
       return prev.id == -1 ? Edge(*this, u.id, v.id) : INVALID;
@@ -218,5 +171,4 @@
   /// \sa concept::Graph.
   ///
-  /// \sa FullGraphBase
   /// \sa FullUGraph
   ///
@@ -246,10 +198,35 @@
       Parent::getNotifier(Edge()).build();
     }
+
+    /// \brief Returns the node with the given index.
+    ///
+    /// Returns the node with the given index. Because it is a
+    /// static size graph the node's of the graph can be indiced
+    /// by the range from 0 to \e nodeNum()-1 and the index of
+    /// the node can accessed by the \e index() member.
+    Node operator()(int index) const { return Parent::operator()(index); }
+
+    /// \brief Returns the index of the node.
+    ///
+    /// Returns the index of the node. Because it is a
+    /// static size graph the node's of the graph can be indiced
+    /// by the range from 0 to \e nodeNum()-1 and the index of
+    /// the node can accessed by the \e index() member.
+    int index(const Node& node) const { return Parent::index(node); }
+
+    /// \brief Returns the edge connects the given nodes.
+    ///
+    /// Returns the edge connects the given nodes.
+    Edge edge(const Node& u, const Node& v) const { 
+      return Parent::edge(u, v); 
+    }
+
+    /// \brief Number of nodes.
+    int nodeNum() const { return Parent::nodeNum(); }
+    /// \brief Number of edges.
+    int edgeNum() const { return Parent::edgeNum(); }
   };
 
 
-  /// \brief Base of the FullUGrpah.
-  ///
-  /// Base of the FullUGrpah.
   class FullUGraphBase {
     int _nodeNum;
@@ -262,57 +239,30 @@
     class Edge;
 
+  protected:
+
+    FullUGraphBase() {}
+
+    void construct(int n) { _nodeNum = n; _edgeNum = n * (n - 1) / 2; }
+
   public:
 
-    FullUGraphBase() {}
-
-
-    ///Creates a full graph with \c n nodes.
-    void construct(int n) { _nodeNum = n; _edgeNum = n * (n - 1) / 2; }
-
-    /// \brief Returns the node with the given index.
-    ///
-    /// Returns the node with the given index. Because it is a
-    /// static size graph the node's of the graph can be indiced
-    /// by the range from 0 to \e nodeNum()-1 and the index of
-    /// the node can accessed by the \e index() member.
+
     Node operator()(int index) const { return Node(index); }
-
-    /// \brief Returns the index of the node.
-    ///
-    /// Returns the index of the node. Because it is a
-    /// static size graph the node's of the graph can be indiced
-    /// by the range from 0 to \e nodeNum()-1 and the index of
-    /// the node can accessed by the \e index() member.
     int index(const Node& node) const { return node.id; }
+
+    Edge edge(const Node& u, const Node& v) const { 
+      return Edge(u.id * (u.id - 1) / 2 + v.id);
+    }
 
     typedef True NodeNumTag;
     typedef True EdgeNumTag;
 
-    ///Number of nodes.
     int nodeNum() const { return _nodeNum; }
-    ///Number of edges.
     int edgeNum() const { return _edgeNum; }
 
-    /// Maximum node ID.
-    
-    /// Maximum node ID.
-    ///\sa id(Node)
     int maxNodeId() const { return _nodeNum-1; }
-    /// Maximum edge ID.
-    
-    /// Maximum edge ID.
-    ///\sa id(Edge)
     int maxEdgeId() const { return _edgeNum-1; }
 
-    /// \brief Returns the node from its \c id.
-    ///
-    /// Returns the node from its \c id. If there is not node
-    /// with the given id the effect of the function is undefinied.
     static Node nodeFromId(int id) { return Node(id);}
-
-    /// \brief Returns the edge from its \c id.
-    ///
-    /// Returns the edge from its \c id. If there is not edge
-    /// with the given id the effect of the function is undefinied.
     static Edge edgeFromId(int id) { return Edge(id);}
 
@@ -327,34 +277,7 @@
     }
 
-
-    /// \brief Node ID.
-    ///
-    /// The ID of a valid Node is a nonnegative integer not greater than
-    /// \ref maxNodeId(). The range of the ID's is not surely continuous
-    /// and the greatest node ID can be actually less then \ref maxNodeId().
-    ///
-    /// The ID of the \ref INVALID node is -1.
-    /// \return The ID of the node \c v. 
-
     static int id(Node v) { return v.id; }
-
-    /// \brief Edge ID.
-    ///
-    /// The ID of a valid Edge is a nonnegative integer not greater than
-    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
-    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
-    ///
-    /// The ID of the \ref INVALID edge is -1.
-    ///\return The ID of the edge \c e. 
     static int id(Edge e) { return e.id; }
 
-    /// \brief Finds an edge between two nodes.
-    ///
-    /// Finds an edge from node \c u to node \c v.
-    ///
-    /// If \c prev is \ref INVALID (this is the default value), then
-    /// It finds the first edge from \c u to \c v. Otherwise it looks for
-    /// the next edge from \c u to \c v after \c prev.
-    /// \return The found edge or INVALID if there is no such an edge.
     Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
       if (prev.id != -1 || u.id <= v.id) return Edge(-1);
@@ -457,5 +380,4 @@
   /// it does not contain the loop edges.
   ///
-  /// \sa FullUGraphBase
   /// \sa FullGraph
   ///
@@ -486,4 +408,53 @@
       Parent::getNotifier(Edge()).build();
     }
+
+    /// \brief Returns the node with the given index.
+    ///
+    /// Returns the node with the given index. Because it is a
+    /// static size graph the node's of the graph can be indiced
+    /// by the range from 0 to \e nodeNum()-1 and the index of
+    /// the node can accessed by the \e index() member.
+    Node operator()(int index) const { return Parent::operator()(index); }
+
+    /// \brief Returns the index of the node.
+    ///
+    /// Returns the index of the node. Because it is a
+    /// static size graph the node's of the graph can be indiced
+    /// by the range from 0 to \e nodeNum()-1 and the index of
+    /// the node can accessed by the \e index() member.
+    int index(const Node& node) const { return Parent::index(node); }
+
+    /// \brief Number of nodes.
+    int nodeNum() const { return Parent::nodeNum(); }
+    /// \brief Number of edges.
+    int edgeNum() const { return Parent::edgeNum(); }
+    /// \brief Number of undirected edges.
+    int uEdgeNum() const { return Parent::uEdgeNum(); }
+
+    /// \brief Returns the edge connects the given nodes.
+    ///
+    /// Returns the edge connects the given nodes.
+    Edge edge(const Node& u, const Node& v) const { 
+      if (Parent::index(u) > Parent::index(v)) {
+        return Parent::direct(Parent::edge(u, v), true);
+      } else if (Parent::index(u) == Parent::index(v)) {
+        return INVALID;
+      } else {
+        return Parent::direct(Parent::edge(v, u), false); 
+      }
+    }
+
+    /// \brief Returns the undirected edge connects the given nodes.
+    ///
+    /// Returns the undirected edge connects the given nodes.
+    UEdge uEdge(const Node& u, const Node& v) const {
+      if (Parent::index(u) > Parent::index(v)) {
+        return Parent::edge(u, v);
+      } else if (Parent::index(u) == Parent::index(v)) {
+        return INVALID;
+      } else {
+        return Parent::edge(v, u);
+      }
+    }
   };
 
@@ -496,4 +467,14 @@
 
     int _edgeNum;
+
+  protected:
+
+    FullBpUGraphBase() {}
+
+    void construct(int aNodeNum, int bNodeNum) {
+      _aNodeNum = aNodeNum;
+      _bNodeNum = bNodeNum;
+      _edgeNum = aNodeNum * bNodeNum;
+    }
 
   public:
@@ -534,8 +515,18 @@
     };
 
-    void construct(int aNodeNum, int bNodeNum) {
-      _aNodeNum = aNodeNum;
-      _bNodeNum = bNodeNum;
-      _edgeNum = aNodeNum * bNodeNum;
+    Node aNode(int index) const { return Node(index << 1); }
+    Node bNode(int index) const { return Node((index << 1) + 1); }
+
+    int aNodeIndex(const Node& node) const { return node.id >> 1; }
+    int bNodeIndex(const Node& node) const { return node.id >> 1; }
+
+    UEdge uEdge(const Node& u, const Node& v) const { 
+      if (((u.id ^ v.id) & 1) != 1) {
+        return UEdge(-1);
+      } else if ((u.id & 1) == 0) {
+        return UEdge((u.id >> 1) * _bNodeNum + (v.id >> 1));
+      } else {
+        return UEdge((v.id >> 1) * _bNodeNum + (u.id >> 1));
+      }
     }
 
@@ -651,11 +642,4 @@
     }
 
-    static Node aNode(int index) {
-      return Node(index << 1);
-    }
-
-    static Node bNode(int index) {
-      return Node((index << 1) + 1);
-    }
 
     typedef True NodeNumTag;
@@ -667,4 +651,16 @@
     int uEdgeNum() const { return _edgeNum; }
 
+
+    typedef True FindEdgeTag;
+    UEdge findUEdge(Node u, Node v, UEdge prev = INVALID) const {
+      if (prev.id != -1 || ((u.id ^ v.id) & 1) != 1) {
+        return UEdge(-1);
+      } else if ((u.id & 1) == 0) {
+        return UEdge((u.id >> 1) * _bNodeNum + (v.id >> 1));
+      } else {
+        return UEdge((v.id >> 1) * _bNodeNum + (u.id >> 1));
+      }
+    }
+
   };
 
@@ -680,7 +676,4 @@
   /// It is completely static, so you can neither add nor delete either
   /// edges or nodes.
-  ///
-  /// \sa FullUGraphBase
-  /// \sa FullGraph
   ///
   /// \author Balazs Dezso
@@ -701,4 +694,5 @@
     /// \brief Resize the graph
     ///
+    /// Resize the graph
     void resize(int n, int m) {
       Parent::getNotifier(Edge()).clear();
@@ -714,4 +708,70 @@
       Parent::getNotifier(Edge()).build();
     }
+
+    /// \brief Number of nodes.
+    int nodeNum() const { return Parent::nodeNum(); }
+    /// \brief Number of A-nodes.
+    int aNodeNum() const { return Parent::aNodeNum(); }
+    /// \brief Number of B-nodes.
+    int bNodeNum() const { return Parent::bNodeNum(); }
+    /// \brief Number of edges.
+    int edgeNum() const { return Parent::edgeNum(); }
+    /// \brief Number of undirected edges.
+    int uEdgeNum() const { return Parent::uEdgeNum(); }
+
+
+    using Parent::aNode;
+    using Parent::bNode;
+
+    /// \brief Returns the A-node with the given index.
+    ///
+    /// Returns the A-node with the given index. Because it is a
+    /// static size graph the node's of the graph can be indiced
+    /// by the range from 0 to \e aNodeNum()-1 and the index of
+    /// the node can accessed by the \e aNodeIndex() member.
+    Node aNode(int index) const { return Parent::aNode(index); }
+
+    /// \brief Returns the B-node with the given index.
+    ///
+    /// Returns the B-node with the given index. Because it is a
+    /// static size graph the node's of the graph can be indiced
+    /// by the range from 0 to \e bNodeNum()-1 and the index of
+    /// the node can accessed by the \e bNodeIndex() member.
+    Node bNode(int index) const { return Parent::bNode(index); }
+
+    /// \brief Returns the index of the A-node.
+    ///
+    /// Returns the index of the A-node. Because it is a
+    /// static size graph the node's of the graph can be indiced
+    /// by the range from 0 to \e aNodeNum()-1 and the index of
+    /// the node can accessed by the \e aNodeIndex() member.
+    int aNodeIndex(const Node& node) const { return Parent::aNodeIndex(node); }
+
+    /// \brief Returns the index of the B-node.
+    ///
+    /// Returns the index of the B-node. Because it is a
+    /// static size graph the node's of the graph can be indiced
+    /// by the range from 0 to \e bNodeNum()-1 and the index of
+    /// the node can accessed by the \e bNodeIndex() member.
+    int bNodeIndex(const Node& node) const { return Parent::bNodeIndex(node); }
+
+    /// \brief Returns the edge connects the given nodes.
+    ///
+    /// Returns the edge connects the given nodes.
+    Edge edge(const Node& u, const Node& v) const {
+      UEdge uedge = Parent::uEdge(u, v);
+      if (uedge != INVALID) {
+        return Parent::direct(uedge, Parent::aNode(u));
+      } else {
+        return INVALID;
+      }
+    }
+
+    /// \brief Returns the undirected edge connects the given nodes.
+    ///
+    /// Returns the undirected edge connects the given nodes.
+    UEdge uEdge(const Node& u, const Node& v) const {
+      return Parent::uEdge(u, v);
+    }
   };
 
