diff --git a/graph/graph.cpp b/graph/graph.cpp
index 04d6cd812ec3c8f0cb3610417e97b0d2a2395568..71e518e771d142594316d475e4add3128b035b6f 100644
--- a/graph/graph.cpp
+++ b/graph/graph.cpp
@@ -180,6 +180,12 @@
 #define COST_TABLE "BENCH_COST"
 
 
+//=============================================================================
+// How many bytes does the bitstring in one element of the adjacency list have?
+//=============================================================================
+
+#define BITSTRING_BYTES 4
+
 //=============================================================================
 // Include Files:
 //=============================================================================
@@ -358,6 +364,361 @@ long str_int(str_t digits) {
 }
 
 
+//=============================================================================
+// Class for Linked List Element in Node Set (contains bit array):
+//=============================================================================
+
+class NodeSetElem {
+	public:
+
+	// Constructor:
+	NodeSetElem(int start_value)
+	{
+		next_  = (NodeSetElem *) 0;
+		start_ = start_value;
+		unsigned char *p = bits_;
+		for(int i = BITSTRING_BYTES; i > 0; i--)
+			*p++ = '\0';
+	}
+
+	// Get start node number (to be added to all numbers in bit array):
+	inline int start() const {
+		return start_;
+	}
+
+	// Get link to next list elem:
+	inline NodeSetElem *next() const {
+		return next_;
+	}
+
+	// Set link to next list elem:
+	inline void set_next(NodeSetElem *next_elem) {
+		next_ = next_elem;
+	}
+
+	// Get bit in bit array:
+	inline bool bit(int index) const {
+
+		// Check validity, part I:
+		if(index < 0) {
+			std::cerr << "get_bit: Invalid bit index (negative)!";
+			exit(3);
+		}
+
+		// Determine position in bit array:
+		int bit_no = index % 8;
+		index = index / 8;
+
+		// Check parameter, part II:
+		if(index >= BITSTRING_BYTES) {
+			std::cerr << "get_bit: Invalid bit index (too large)!";
+			exit(4);
+		}
+
+		// Get bit:
+		return (bits_[index] & ((0x1) << bit_no)) != 0;
+	}
+
+	// Set bit in bit array:
+	inline void set_bit(int index) {
+
+		// Check validity, part I:
+		if(index < 0) {
+			std::cerr << "set_bit: Invalid bit index (negative)!";
+			exit(5);
+		}
+
+		// Determine position in bit array:
+		int bit_no = index % 8;
+		index = index / 8;
+
+		// Check parameter, part II:
+		if(index >= BITSTRING_BYTES) {
+			std::cerr << "set_bit: Invalid bit index (too large)!";
+			exit(6);
+		}
+
+		// Set bit:
+		bits_[index] |= (0x1) << bit_no;
+	}
+
+	// Find next set bit in bit array with position >= index:
+	inline int next_bit(int index) {
+
+		// Check validity, part I:
+		if(index < 0) {
+			std::cerr << "next_bit: Invalid bit index (negative)!";
+			exit(7);
+		}
+
+		// Determine position in bit array:
+		int bit_no = index % 8;
+		index = index / 8;
+
+		// Check parameter, part II:
+		if(index >= BITSTRING_BYTES) {
+			std::cerr << "next_bit: Invalid bit index (too large)!";
+			exit(8);
+		}
+
+		// Find next set bit (-1 if there is no further bit):
+		unsigned char byte = bits_[index];
+		if(byte != 0) {
+			switch(bit_no) {
+				case 0:
+					if(byte & 0x1)
+						return (index*8);
+					/* FALLTHROUGH */
+				case 1:
+					if(byte & 0x2)
+						return (index*8 + 1);
+					/* FALLTHROUGH */
+				case 2:
+					if(byte & 0x4)
+						return (index*8 + 2);
+					/* FALLTHROUGH */
+				case 3:
+					if(byte & 0x8)
+						return (index*8 + 3);
+					/* FALLTHROUGH */
+				case 4:
+					if(byte & 0x10)
+						return (index*8 + 4);
+					/* FALLTHROUGH */
+				case 5:
+					if(byte & 0x20)
+						return (index*8 + 5);
+					/* FALLTHROUGH */
+				case 6:
+					if(byte & 0x40)
+						return (index*8 + 6);
+					/* FALLTHROUGH */
+				case 7:
+					if(byte & 0x80)
+						return (index*8 + 7);
+			}
+		}
+		while(++index < BITSTRING_BYTES) {
+			byte = bits_[index];
+			if(byte != 0) {
+				if(byte & 0x1)
+					return (index*8);
+				if(byte & 0x2)
+					return (index*8 + 1);
+				if(byte & 0x4)
+					return (index*8 + 2);
+				if(byte & 0x8)
+					return (index*8 + 3);
+				if(byte & 0x10)
+					return (index*8 + 4);
+				if(byte & 0x20)
+					return (index*8 + 5);
+				if(byte & 0x40)
+					return (index*8 + 6);
+				if(byte & 0x80)
+					return (index*8 + 7);
+			}
+		}
+
+		// No set bit found:
+		return -1;
+	}
+
+	// Attributes:
+	private:
+	NodeSetElem *next_;
+	int start_;
+	unsigned char bits_[BITSTRING_BYTES];
+};
+
+//-----------------------------------------------------------------------------
+// Pointer Type for Node Number List Element:
+//-----------------------------------------------------------------------------
+
+typedef NodeSetElem *node_set_elem_t;
+
+#define NODE_SET_ELEM_NULL (static_cast<node_set_elem_t>(0))
+
+
+//=============================================================================
+// Class for Scan/Cursor over Node Set (set of non-negative integers):
+//=============================================================================
+
+class NodeSetScan {
+	public:
+
+	// Constructor:
+	NodeSetScan(node_set_elem_t list)
+	{
+		list_ = list;
+		curr_elem_  = list;
+		if(curr_elem_ != NODE_SET_ELEM_NULL)
+			start_ = curr_elem_->start();
+		else
+			start_ = 0;
+		next_index_ = 0;
+	}
+
+	// Get next node number in set (-1 if there is no further element):
+	int next() {
+		// Check whether we are at the end of the list:
+		if(curr_elem_ == NODE_SET_ELEM_NULL)
+			return -1;
+
+		// Try to find next value in current list element:
+		if(next_index_ < BITSTRING_BYTES * 8) {
+			int bit = curr_elem_->next_bit(next_index_);
+			if(bit >= 0) {
+				next_index_ = bit + 1;
+				return start_ + bit;
+			}
+		}
+
+		// Move to next list element:
+		curr_elem_ = curr_elem_->next();
+		if(curr_elem_ == NODE_SET_ELEM_NULL)
+			return -1;
+
+		// We know that list elements are non-empty:
+		start_ = curr_elem_->start();
+		int bit = curr_elem_->next_bit(next_index_);
+		next_index_ = bit + 1;
+		return start_ + bit;
+	}
+
+	// Reset scan to start:
+	void reset() {
+		curr_elem_ = list_;
+		if(curr_elem_ != NODE_SET_ELEM_NULL)
+			start_ = curr_elem_->start();
+		else
+			start_ = 0;
+		next_index_ = 0;
+	}
+
+	// Attributes:
+	private:
+	node_set_elem_t list_;
+	node_set_elem_t curr_elem_;
+	int start_;
+	int next_index_;
+};
+
+//-----------------------------------------------------------------------------
+// Pointer Type for Node Number List Element:
+//-----------------------------------------------------------------------------
+
+typedef NodeSetScan *node_set_scan_t;
+
+#define NODE_SET_SCAN_NULL (static_cast<node_set_scan_t>(0))
+
+
+
+//=============================================================================
+// Class for Node Set (represented as linked list of bit arrays):
+//=============================================================================
+
+// Note that this actually manages a set of node numbers,
+// i.e. non-negative integers.
+
+class NodeSet {
+
+	public:
+
+	// Constructor:
+	NodeSet() {
+		list_ = NODE_SET_ELEM_NULL;
+	}
+
+	// Destructor:
+	~NodeSet() {
+		node_set_elem_t next = NODE_SET_ELEM_NULL;
+		for(node_set_elem_t elem = list_; elem; elem = next) {
+			next = elem->next();
+			delete elem;
+		}
+	}
+
+	// Insert a node number:
+	void insert(int n) {
+		int start = n / (BITSTRING_BYTES * 8);
+		int index = n % (BITSTRING_BYTES * 8);
+
+		// Handle empty list:
+		if(list_ == NODE_SET_ELEM_NULL) {
+			list_ = new NodeSetElem(start);
+			list_->set_bit(index);
+			return;
+		}
+
+		// Handle insertion into first element:
+		if(list_->start() == start) {
+			list_->set_bit(index);
+			return;
+		}
+
+		// Handle insertion before first element:
+		if(list_->start() > start) {
+			node_set_elem_t elem = new NodeSetElem(start);
+			elem->set_bit(index);
+			elem->set_next(list_);
+			list_ = elem;
+		}
+
+		// Now we can have a pointer to the previous element:
+		node_set_elem_t prev = list_;
+		node_set_elem_t next = prev->next();
+		while(next != NODE_SET_ELEM_NULL) {
+			int next_start = next->start();
+			// Insert into next element:
+			if(next_start == start) {
+				next->set_bit(index);
+				return;
+			}
+			// Insert before next element:
+			if(next_start > start) {
+				node_set_elem_t elem = new NodeSetElem(start);
+				elem->set_bit(index);
+				elem->set_next(next);
+				prev->set_next(elem);
+			}
+			// Now we know that next_start < start, move on:
+			prev = next;
+			next = next->next();
+		}
+
+		// Insert node at the very end of the list:
+		node_set_elem_t elem = new NodeSetElem(start);
+		elem->set_bit(index);
+		prev->set_next(elem);
+	}
+
+	// Check whether a nonnegative integer exists in the set:
+	bool contains(int n) {
+		int start = n / (BITSTRING_BYTES * 8);
+		int index = n % (BITSTRING_BYTES * 8);
+		for(node_set_elem_t elem = list_; elem; elem = elem->next()) {
+			int elem_start = elem->start();
+			if(elem_start == start)
+				return elem->bit(index);
+			if(elem_start > start)
+				return false;
+		}
+	}
+
+	// Attributes:
+	private:
+	node_set_elem_t list_;
+};
+
+//-----------------------------------------------------------------------------
+// Pointer Type for Node Set (really a set of non-negative integers):
+//-----------------------------------------------------------------------------
+
+typedef NodeSet *node_set_t;
+
+#define NODE_SET_NULL (static_cast<node_set_t>(0))
+
 //=============================================================================
 // Class for Graph Nodes (one line of the adjacency matrix):
 //=============================================================================