using namespace lemon;
directive is added to the code at the beginning.
For using ListDigraph, you must include the header file list_graph.h like this:
#include <lemon/list_graph.h>
The default constructor of the class creates an empty digraph.
ListDigraph g;
The nodes and the arcs of a graph are identified by two data types called ListDigraph::Node and ListDigraph::Arc. You can add new items to the graph using the member functions addNode() and addArc(), like this:
ListDigraph::Node x = g.addNode(); ListDigraph::Node y = g.addNode(); ListDigraph::Node z = g.addNode(); g.addArc(x,y); g.addArc(y,z); g.addArc(z,x);
Of course, addArc() also returns the created arc:
ListDigraph::Arc arc = g.addArc(x,z);
Parallel and loop arcs are also supported.
ListDigraph::Arc parallel = g.addArc(x,y); ListDigraph::Arc loop = g.addArc(x,x);
Node
objects).
if (g.source(loop) == g.target(loop)) std::cout << "This is a loop arc" << std::endl;
Each graph item has a non-negative integer identifier, which can be obtained using the id() function of the graph structure. These identifiers are unique with respect to a certain item type in a graph, but a node and an arc may have the same id.
std::cout << "Arc " << g.id(arc) << " goes from node " << g.id(g.source(arc)) << " to node " << g.id(g.target(arc)) << std::endl;
Node
and Arc
types are typically simple wrapper classes for a single int
value, which is the identifier of the item.
int cnt = 0; for (ListDigraph::NodeIt n(g); n != INVALID; ++n) cnt++; std::cout << "Number of nodes: " << cnt << std::endl;
ListDigraph::NodeIt is an iterator class that lists the nodes. The name of an iterator type starts with a name that refers to the iterated objects and ends with 'It'.
Using NodeIt, you must give the graph object to the constructor and the iterator will be set to the first node. The next node is obtained by the prefix ++ operator. If there are no more nodes in the graph, the iterator will be set to INVALID, which is exploited in the stop condition of the loop.
Node
or Arc
object.
As an other example, the following code adds a full graph to the existing nodes.
for (ListDigraph::NodeIt u(g); u != INVALID; ++u) for (ListDigraph::NodeIt v(g); v != INVALID; ++v) if (u != v) g.addArc(u, v);
operator*
(). This is not confusing, since the program context always indicates whether we refer to the iterator or to the graph item (they do not have conflicting functionalities).
for (ListDigraph::NodeIt u(g); u != INVALID; ++u) for (ListDigraph::NodeIt v(g); v != INVALID; ++v) if (u < v) g.addArc(u, v);
int cnt = 0; for (ListDigraph::ArcIt a(g); a != INVALID; ++a) cnt++; std::cout << "Number of arcs: " << cnt << std::endl;
Finally, you can also list the arcs starting from or arriving at a certain node with ListDigraph::OutArcIt and ListDigraph::InArcIt. Their usage is the same, but you must also give the node to the constructor.
int cnt = 0; for (ListDigraph::OutArcIt a(g, x); a != INVALID; ++a) cnt++; std::cout << "Number of arcs leaving the node 'x': " << cnt << std::endl;
By principle, the graph classes represent only the pure structure of the graph (i.e. the nodes and arcs and their connections). All data that are assigned to the items of the graph (e.g. node labels, arc costs or capacities) must be stored separately using maps.
std::map
, since they provide O(1) time access to the elements instead of O(log n).int
values to each node, you have to allocate a NodeMap<int>.
ListDigraph::NodeMap<int> map(g);
As you see, the graph you want to assign a map is given to the constructor. Then you can access its element as if it were a vector.
map[x] = 2; map[y] = 3; map[z] = map[x] + map[y];
Any kind of data can be assigned to the graph items (assuming that the type has a default constructor).
ListDigraph::NodeMap<std::string> name(g); name[x] = "Node A"; name[y] = "Node B";
As a more complex example, let us create a map that assigns char
labels to the nodes.
ListDigraph::NodeMap<char> label(g); char ch = 'A'; for (ListDigraph::NodeIt n(g); n != INVALID; ++n) label[n] = ch++;
When you create a map, you can also give an initial value of the elements as a second parameter. For example, the following code puts the number of outgoing arcs for each node in a map.
ListDigraph::NodeMap<int> out_deg(g, 0); for (ListDigraph::ArcIt a(g); a != INVALID; ++a) out_deg[g.source(a)]++;
The name of a source file is written lowercase and the words are separated with underscores (e.g. list_graph.h). All header files are located in the lemon
subdirectory, so you can include them like this.
#include <lemon/header_file.h>
The name of a class or any type looks like the following (e.g. ListDigraph, Node, NodeIt etc.).
AllWordsCapitalizedWithoutUnderscores
The name of a function looks like the following (e.g. source(), target(), countNodes(), countArcs() etc.).
firstWordLowerCaseRestCapitalizedWithoutUnderscores
The names of constants and macros look like the following (e.g. INVALID).
ALL_UPPER_CASE_WITH_UNDERSCORES
For more details, see LEMON Coding Style.
<< 2 Compile Your First Code | Home | 4 Algorithms >>