[Lemon-commits] [lemon_svn] deba: r2575 - hugo/trunk/lemon
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:53:39 CET 2006
Author: deba
Date: Thu Feb 23 16:10:45 2006
New Revision: 2575
Modified:
hugo/trunk/lemon/list_graph.h
Log:
ListBpUGraph
Modified: hugo/trunk/lemon/list_graph.h
==============================================================================
--- hugo/trunk/lemon/list_graph.h (original)
+++ hugo/trunk/lemon/list_graph.h Thu Feb 23 16:10:45 2006
@@ -636,6 +636,338 @@
}
};
+
+ class ListBpUGraphBase {
+ public:
+
+ class NodeSetError : public LogicError {
+ virtual const char* exceptionName() const {
+ return "lemon::ListBpUGraph::NodeSetError";
+ }
+ };
+
+ protected:
+
+ struct NodeT {
+ int first_edge, next_node;
+ };
+
+ struct EdgeT {
+ int aNode, prev_out, next_out;
+ int bNode, prev_in, next_in;
+ };
+
+ std::vector<NodeT> aNodes;
+ std::vector<NodeT> bNodes;
+
+ std::vector<EdgeT> edges;
+
+ int first_anode;
+ int first_free_anode;
+
+ int first_bnode;
+ int first_free_bnode;
+
+ int first_free_edge;
+
+ public:
+
+ class Node {
+ friend class ListBpUGraphBase;
+ 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<i.id;}
+ };
+
+ class Edge {
+ friend class ListBpUGraphBase;
+ protected:
+ int id;
+
+ Edge(int _id) { id = _id;}
+ public:
+ Edge() {}
+ Edge (Invalid) { id = -1; }
+ bool operator==(const Edge i) const {return id==i.id;}
+ bool operator!=(const Edge i) const {return id!=i.id;}
+ bool operator<(const Edge i) const {return id<i.id;}
+ };
+
+ ListBpUGraphBase()
+ : first_anode(-1), first_free_anode(-1),
+ first_bnode(-1), first_free_bnode(-1),
+ first_free_edge(-1) {}
+
+ void firstANode(Node& node) const {
+ node.id = first_anode != -1 ? (first_anode << 1) : -1;
+ }
+ void nextANode(Node& node) const {
+ node.id = aNodes[node.id >> 1].next_node;
+ }
+
+ void firstBNode(Node& node) const {
+ node.id = first_bnode != -1 ? (first_bnode << 1) + 1 : -1;
+ }
+ void nextBNode(Node& node) const {
+ node.id = aNodes[node.id >> 1].next_node;
+ }
+
+ void first(Node& node) const {
+ if (first_anode != -1) {
+ node.id = (first_anode << 1);
+ } else if (first_bnode != -1) {
+ node.id = (first_bnode << 1) + 1;
+ } else {
+ node.id = -1;
+ }
+ }
+ void next(Node& node) const {
+ if (aNode(node)) {
+ node.id = aNodes[node.id >> 1].next_node;
+ if (node.id == -1) {
+ if (first_bnode != -1) {
+ node.id = (first_bnode << 1) + 1;
+ }
+ }
+ } else {
+ node.id = bNodes[node.id >> 1].next_node;
+ }
+ }
+
+ void first(Edge& edge) const {
+ int aNodeId = first_anode;
+ while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
+ aNodeId = aNodes[aNodeId].next_node != -1 ?
+ aNodes[aNodeId].next_node >> 1 : -1;
+ }
+ if (aNodeId != -1) {
+ edge.id = aNodes[aNodeId].first_edge;
+ } else {
+ edge.id = -1;
+ }
+ }
+ void next(Edge& edge) const {
+ int aNodeId = edges[edge.id].aNode >> 1;
+ edge.id = edges[edge.id].next_out;
+ if (edge.id == -1) {
+ aNodeId = aNodes[aNodeId].next_node != -1 ?
+ aNodes[aNodeId].next_node >> 1 : -1;
+ while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
+ aNodeId = aNodes[aNodeId].next_node != -1 ?
+ aNodes[aNodeId].next_node >> 1 : -1;
+ }
+ if (aNodeId != -1) {
+ edge.id = aNodes[aNodeId].first_edge;
+ } else {
+ edge.id = -1;
+ }
+ }
+ }
+
+ void firstOut(Edge& edge, const Node& node) const {
+ LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
+ edge.id = aNodes[node.id >> 1].first_edge;
+ }
+ void nextOut(Edge& edge) const {
+ edge.id = edges[edge.id].next_out;
+ }
+
+ void firstIn(Edge& edge, const Node& node) const {
+ LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
+ edge.id = bNodes[node.id >> 1].first_edge;
+ }
+ void nextIn(Edge& edge) const {
+ edge.id = edges[edge.id].next_in;
+ }
+
+ static int id(const Node& node) {
+ return node.id;
+ }
+ static Node nodeFromId(int id) {
+ return Node(id);
+ }
+ int maxNodeId() const {
+ return aNodes.size() > bNodes.size() ?
+ aNodes.size() * 2 - 2 : bNodes.size() * 2 - 1;
+ }
+
+ static int id(const Edge& edge) {
+ return edge.id;
+ }
+ static Edge edgeFromId(int id) {
+ return Edge(id);
+ }
+ int maxEdgeId() const {
+ return edges.size();
+ }
+
+ static int aNodeId(const Node& node) {
+ return node.id >> 1;
+ }
+ static Node fromANodeId(int id, Node) {
+ return Node(id << 1);
+ }
+ int maxANodeId() const {
+ return aNodes.size();
+ }
+
+ static int bNodeId(const Node& node) {
+ return node.id >> 1;
+ }
+ static Node fromBNodeId(int id) {
+ return Node((id << 1) + 1);
+ }
+ int maxBNodeId() const {
+ return bNodes.size();
+ }
+
+ Node aNode(const Edge& edge) const {
+ return Node(edges[edge.id].aNode);
+ }
+ Node bNode(const Edge& edge) const {
+ return Node(edges[edge.id].bNode);
+ }
+
+ static bool aNode(const Node& node) {
+ return (node.id & 1) == 0;
+ }
+
+ static bool bNode(const Node& node) {
+ return (node.id & 1) == 1;
+ }
+
+ Node addANode() {
+ int aNodeId;
+ if (first_free_anode == -1) {
+ aNodeId = aNodes.size();
+ aNodes.push_back(NodeT());
+ } else {
+ aNodeId = first_free_anode;
+ first_free_anode = aNodes[first_free_anode].next_node;
+ }
+ aNodes[aNodeId].next_node =
+ first_anode != -1 ? (first_anode << 1) : -1;
+ first_anode = aNodeId;
+ aNodes[aNodeId].first_edge = -1;
+ return Node(aNodeId << 1);
+ }
+
+ Node addBNode() {
+ int bNodeId;
+ if (first_free_anode == -1) {
+ bNodeId = bNodes.size();
+ bNodes.push_back(NodeT());
+ } else {
+ bNodeId = first_free_bnode;
+ first_free_bnode = bNodes[first_free_bnode].next_node;
+ }
+ bNodes[bNodeId].next_node =
+ first_bnode != -1 ? (first_bnode << 1) + 1 : -1;
+ first_bnode = bNodeId;
+ bNodes[bNodeId].first_edge = -1;
+ return Node((bNodeId << 1) + 1);
+ }
+
+ Edge addEdge(const Node& source, const Node& target) {
+ LEMON_ASSERT(((source.id ^ target.id) & 1) == 1, NodeSetError());
+ int edgeId;
+ if (first_free_edge != -1) {
+ edgeId = first_free_edge;
+ first_free_edge = edges[edgeId].next_out;
+ } else {
+ edgeId = edges.size();
+ edges.push_back(EdgeT());
+ }
+ if ((source.id & 1) == 0) {
+ edges[edgeId].aNode = source.id;
+ edges[edgeId].bNode = target.id;
+ } else {
+ edges[edgeId].aNode = target.id;
+ edges[edgeId].bNode = source.id;
+ }
+ edges[edgeId].next_out = aNodes[edges[edgeId].aNode >> 1].first_edge;
+ edges[edgeId].prev_out = -1;
+ if (aNodes[edges[edgeId].aNode >> 1].first_edge != -1) {
+ edges[aNodes[edges[edgeId].aNode >> 1].first_edge].prev_out = edgeId;
+ }
+ aNodes[edges[edgeId].aNode >> 1].first_edge = edgeId;
+ edges[edgeId].next_in = bNodes[edges[edgeId].bNode >> 1].first_edge;
+ edges[edgeId].prev_in = -1;
+ if (bNodes[edges[edgeId].bNode >> 1].first_edge != -1) {
+ edges[bNodes[edges[edgeId].bNode >> 1].first_edge].prev_in = edgeId;
+ }
+ bNodes[edges[edgeId].bNode >> 1].first_edge = edgeId;
+ return Edge(edgeId);
+ }
+
+ void erase(const Node& node) {
+ if (aNode(node)) {
+ int aNodeId = node.id >> 1;
+ aNodes[aNodeId].next_node = first_free_anode;
+ first_free_anode = aNodeId;
+ } else {
+ int bNodeId = node.id >> 1;
+ bNodes[bNodeId].next_node = first_free_bnode;
+ first_free_bnode = bNodeId;
+ }
+ }
+
+ void erase(const Edge& edge) {
+ if (edges[edge.id].prev_out != -1) {
+ edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
+ } else {
+ aNodes[edges[edge.id].aNode].first_edge = edges[edge.id].next_out;
+ }
+ if (edges[edge.id].next_out != -1) {
+ edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;
+ }
+ if (edges[edge.id].prev_in != -1) {
+ edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
+ } else {
+ bNodes[edges[edge.id].bNode].first_edge = edges[edge.id].next_in;
+ }
+ if (edges[edge.id].next_in != -1) {
+ edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;
+ }
+ edges[edge.id].next_out = first_free_edge;
+ first_free_edge = edge.id;
+ }
+
+ void clear() {
+ aNodes.clear();
+ bNodes.clear();
+ edges.clear();
+ first_anode = -1;
+ first_free_anode = -1;
+ first_bnode = -1;
+ first_free_bnode = -1;
+ first_free_edge = -1;
+ }
+
+ };
+
+
+ typedef BpUGraphExtender< BpUGraphBaseExtender<
+ ListBpUGraphBase> > ExtendedListBpUGraphBase;
+
+ /// \ingroup graphs
+ ///
+ /// \brief A smart bipartite undirected graph class.
+ ///
+ /// This is a bipartite undirected graph implementation.
+ /// Except from this it conforms to
+ /// the \ref concept::BpUGraph "BpUGraph" concept.
+ /// \sa concept::BpUGraph.
+ ///
+ class ListBpUGraph : public ExtendedListBpUGraphBase {};
+
/// @}
} //namespace lemon
More information about the Lemon-commits
mailing list