cphb/chapter11.tex

770 lines
22 KiB
TeX
Raw Normal View History

2016-12-28 23:54:51 +01:00
\chapter{Basics of graphs}
2017-01-07 15:34:11 +01:00
Many programming problems can be solved by
2017-02-17 21:13:30 +01:00
modeling the problem as a graph problem
2017-02-04 23:59:31 +01:00
and using an appropriate graph algorithm.
2017-01-07 15:34:11 +01:00
A typical example of a graph is a network
of roads and cities in a country.
Sometimes, though, the graph is hidden
2017-02-17 21:13:30 +01:00
in the problem and it may be difficult to detect it.
2017-01-07 15:34:11 +01:00
2017-02-04 23:59:31 +01:00
This part of the book discusses graph algorithms,
especially focusing on topics that
are important in competitive programming.
2017-02-05 00:04:18 +01:00
In this chapter, we go through concepts
2017-02-04 23:59:31 +01:00
related to graphs,
and study different ways to represent graphs in algorithms.
2017-01-07 15:34:11 +01:00
2017-02-17 21:13:30 +01:00
\section{Graph terminology}
2017-01-07 15:34:11 +01:00
\index{graph}
\index{node}
\index{edge}
A \key{graph} consists of \key{nodes}
2017-05-07 20:18:56 +02:00
and \key{edges}. In this book,
2017-01-07 15:34:11 +01:00
the variable $n$ denotes the number of nodes
in a graph, and the variable $m$ denotes
the number of edges.
2017-02-04 23:59:31 +01:00
The nodes are numbered
2017-01-07 15:34:11 +01:00
using integers $1,2,\ldots,n$.
Note: at SOI we usually say \key{vertex} (plural \key{vertices}) instead of \key{node}.
Vertex and node can be used interchangeably.
We also like to number the vertices 0-based as $0,1,\ldots,n-1$.
2017-02-04 23:59:31 +01:00
For example, the following graph consists of 5 nodes and 7 edges:
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$1$};
\node[draw, circle] (2) at (4,3) {$2$};
\node[draw, circle] (3) at (1,1) {$3$};
\node[draw, circle] (4) at (4,1) {$4$};
\node[draw, circle] (5) at (6,2) {$5$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (1) -- (4);
\path[draw,thick,-] (3) -- (4);
\path[draw,thick,-] (2) -- (4);
\path[draw,thick,-] (2) -- (5);
\path[draw,thick,-] (4) -- (5);
\end{tikzpicture}
\end{center}
2017-01-07 15:34:11 +01:00
\index{path}
2016-12-28 23:54:51 +01:00
A \key{walk} leads from node $a$ to node $b$
2017-02-04 23:59:31 +01:00
through edges of the graph.
A \key{path} is a walk where each node appears
at most once in the path.
The \key{length} of a path (or a walk) is the number of
2017-02-04 23:59:31 +01:00
edges in it.
2017-02-17 21:13:30 +01:00
For example, the above graph contains
2017-05-07 20:18:56 +02:00
a path $1 \rightarrow 3 \rightarrow 4 \rightarrow 5$
2017-05-28 11:07:31 +02:00
of length 3
2017-02-17 21:13:30 +01:00
from node 1 to node 5:
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$1$};
\node[draw, circle] (2) at (4,3) {$2$};
\node[draw, circle] (3) at (1,1) {$3$};
\node[draw, circle] (4) at (4,1) {$4$};
\node[draw, circle] (5) at (6,2) {$5$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (1) -- (4);
\path[draw,thick,-] (3) -- (4);
\path[draw,thick,-] (2) -- (4);
\path[draw,thick,-] (2) -- (5);
\path[draw,thick,-] (4) -- (5);
\path[draw=red,thick,->,line width=2pt] (1) -- (3);
\path[draw=red,thick,->,line width=2pt] (3) -- (4);
\path[draw=red,thick,->,line width=2pt] (4) -- (5);
\end{tikzpicture}
\end{center}
\index{cycle}
A \key{cycle} is a walk where the first and last
node is the same, and every other vertex appears at most once.
2017-02-17 21:13:30 +01:00
For example, the above graph contains
2017-05-07 20:18:56 +02:00
a cycle $1 \rightarrow 3 \rightarrow 4 \rightarrow 1$.
2017-02-17 21:13:30 +01:00
%
% \begin{itemize}
% \item $1 \rightarrow 2 \rightarrow 5$ (length 2)
% \item $1 \rightarrow 4 \rightarrow 5$ (length 2)
% \item $1 \rightarrow 2 \rightarrow 4 \rightarrow 5$ (length 3)
% \item $1 \rightarrow 3 \rightarrow 4 \rightarrow 5$ (length 3)
% \item $1 \rightarrow 4 \rightarrow 2 \rightarrow 5$ (length 3)
% \item $1 \rightarrow 3 \rightarrow 4 \rightarrow 2 \rightarrow 5$ (length 4)
% \end{itemize}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\subsubsection{Connectivity}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\index{connected graph}
2016-12-28 23:54:51 +01:00
2017-05-07 20:18:56 +02:00
A graph is \key{connected} if there is a path
2017-01-07 15:34:11 +01:00
between any two nodes.
For example, the following graph is connected:
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$1$};
\node[draw, circle] (2) at (4,3) {$2$};
\node[draw, circle] (3) at (1,1) {$3$};
\node[draw, circle] (4) at (4,1) {$4$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (2) -- (3);
\path[draw,thick,-] (3) -- (4);
\path[draw,thick,-] (2) -- (4);
\end{tikzpicture}
\end{center}
2017-02-04 23:59:31 +01:00
The following graph is not connected,
because it is not possible to get
from node 4 to any other node:
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$1$};
\node[draw, circle] (2) at (4,3) {$2$};
\node[draw, circle] (3) at (1,1) {$3$};
\node[draw, circle] (4) at (4,1) {$4$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (2) -- (3);
\end{tikzpicture}
\end{center}
2017-02-04 23:59:31 +01:00
\index{component}
2017-01-07 15:34:11 +01:00
The connected parts of a graph are
2017-02-04 23:59:31 +01:00
called its \key{components}.
2017-01-07 15:34:11 +01:00
For example, the following graph
contains three components:
2016-12-28 23:54:51 +01:00
$\{1,\,2,\,3\}$,
2017-01-07 15:34:11 +01:00
$\{4,\,5,\,6,\,7\}$ and
2016-12-28 23:54:51 +01:00
$\{8\}$.
\begin{center}
\begin{tikzpicture}[scale=0.8]
\node[draw, circle] (1) at (1,3) {$1$};
\node[draw, circle] (2) at (4,3) {$2$};
\node[draw, circle] (3) at (1,1) {$3$};
\node[draw, circle] (6) at (6,1) {$6$};
\node[draw, circle] (7) at (9,1) {$7$};
\node[draw, circle] (4) at (6,3) {$4$};
\node[draw, circle] (5) at (9,3) {$5$};
\node[draw, circle] (8) at (11,2) {$8$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (2) -- (3);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (4) -- (5);
\path[draw,thick,-] (5) -- (7);
\path[draw,thick,-] (6) -- (7);
\path[draw,thick,-] (6) -- (4);
\end{tikzpicture}
\end{center}
2017-01-07 15:34:11 +01:00
\index{tree}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
A \key{tree} is a connected graph
2017-02-04 23:59:31 +01:00
that consists of $n$ nodes and $n-1$ edges.
There is a unique path
2017-05-07 20:18:56 +02:00
between any two nodes of a tree.
2017-01-07 15:34:11 +01:00
For example, the following graph is a tree:
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$1$};
\node[draw, circle] (2) at (4,3) {$2$};
\node[draw, circle] (3) at (1,1) {$3$};
\node[draw, circle] (4) at (4,1) {$4$};
\node[draw, circle] (5) at (6,2) {$5$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
%\path[draw,thick,-] (1) -- (4);
\path[draw,thick,-] (2) -- (5);
\path[draw,thick,-] (2) -- (4);
%\path[draw,thick,-] (4) -- (5);
\end{tikzpicture}
\end{center}
2017-01-07 15:34:11 +01:00
\subsubsection{Edge directions}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\index{directed graph}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
A graph is \key{directed}
2017-02-04 23:59:31 +01:00
if the edges can be traversed
in one direction only.
2017-01-07 15:34:11 +01:00
For example, the following graph is directed:
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$1$};
\node[draw, circle] (2) at (4,3) {$2$};
\node[draw, circle] (3) at (1,1) {$3$};
\node[draw, circle] (4) at (4,1) {$4$};
\node[draw, circle] (5) at (6,2) {$5$};
\path[draw,thick,->,>=latex] (1) -- (2);
\path[draw,thick,->,>=latex] (2) -- (4);
\path[draw,thick,->,>=latex] (2) -- (5);
\path[draw,thick,->,>=latex] (4) -- (5);
\path[draw,thick,->,>=latex] (4) -- (1);
\path[draw,thick,->,>=latex] (3) -- (1);
\end{tikzpicture}
\end{center}
2017-02-17 21:13:30 +01:00
The above graph contains
2017-05-07 20:18:56 +02:00
a path $3 \rightarrow 1 \rightarrow 2 \rightarrow 5$
2017-02-17 21:13:30 +01:00
from node $3$ to node $5$,
2017-02-04 23:59:31 +01:00
but there is no path from node $5$ to node $3$.
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\subsubsection{Edge weights}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\index{weighted graph}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
In a \key{weighted} graph, each edge is assigned
a \key{weight}.
2017-05-07 20:18:56 +02:00
The weights are often interpreted as edge lengths.
2017-01-07 15:34:11 +01:00
For example, the following graph is weighted:
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$1$};
\node[draw, circle] (2) at (4,3) {$2$};
\node[draw, circle] (3) at (1,1) {$3$};
\node[draw, circle] (4) at (4,1) {$4$};
\node[draw, circle] (5) at (6,2) {$5$};
\path[draw,thick,-] (1) -- node[font=\small,label=above:5] {} (2);
\path[draw,thick,-] (1) -- node[font=\small,label=left:1] {} (3);
\path[draw,thick,-] (3) -- node[font=\small,label=below:7] {} (4);
\path[draw,thick,-] (2) -- node[font=\small,label=left:6] {} (4);
\path[draw,thick,-] (2) -- node[font=\small,label=above:7] {} (5);
\path[draw,thick,-] (4) -- node[font=\small,label=below:3] {} (5);
\end{tikzpicture}
\end{center}
2017-02-04 23:59:31 +01:00
The length of a path in a weighted graph
2017-05-07 20:18:56 +02:00
is the sum of the edge weights on the path.
2017-02-04 23:59:31 +01:00
For example, in the above graph,
the length of the path
2017-05-07 20:18:56 +02:00
$1 \rightarrow 2 \rightarrow 5$ is $12$,
2017-02-04 23:59:31 +01:00
and the length of the path
2017-01-07 15:34:11 +01:00
$1 \rightarrow 3 \rightarrow 4 \rightarrow 5$ is $11$.
2017-02-04 23:59:31 +01:00
The latter path is the \key{shortest} path from node $1$ to node $5$.
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\subsubsection{Neighbors and degrees}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\index{neighbor}
\index{degree}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
Two nodes are \key{neighbors} or \key{adjacent}
2017-02-04 23:59:31 +01:00
if there is an edge between them.
2017-01-07 15:34:11 +01:00
The \key{degree} of a node
is the number of its neighbors.
For example, in the following graph,
the neighbors of node 2 are 1, 4 and 5,
so its degree is 3.
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$1$};
\node[draw, circle] (2) at (4,3) {$2$};
\node[draw, circle] (3) at (1,1) {$3$};
\node[draw, circle] (4) at (4,1) {$4$};
\node[draw, circle] (5) at (6,2) {$5$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (1) -- (4);
\path[draw,thick,-] (3) -- (4);
\path[draw,thick,-] (2) -- (4);
\path[draw,thick,-] (2) -- (5);
%\path[draw,thick,-] (4) -- (5);
\end{tikzpicture}
\end{center}
2017-02-04 23:59:31 +01:00
The sum of degrees in a graph is always $2m$,
where $m$ is the number of edges,
because each edge
2017-02-17 21:13:30 +01:00
increases the degree of exactly two nodes by one.
2017-02-04 23:59:31 +01:00
For this reason, the sum of degrees is always even.
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\index{regular graph}
\index{complete graph}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
A graph is \key{regular} if the
degree of every node is a constant $d$.
A graph is \key{complete} if the
degree of every node is $n-1$, i.e.,
the graph contains all possible edges
between the nodes.
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\index{indegree}
\index{outdegree}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
In a directed graph, the \key{indegree}
2017-02-04 23:59:31 +01:00
of a node is the number of edges
that end at the node,
and the \key{outdegree} of a node
is the number of edges that start at the node.
2017-01-07 15:34:11 +01:00
For example, in the following graph,
2017-05-07 20:18:56 +02:00
the indegree of node 2 is 2,
2017-02-27 21:13:33 +01:00
and the outdegree of node 2 is 1.
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$1$};
\node[draw, circle] (2) at (4,3) {$2$};
\node[draw, circle] (3) at (1,1) {$3$};
\node[draw, circle] (4) at (4,1) {$4$};
\node[draw, circle] (5) at (6,2) {$5$};
\path[draw,thick,->,>=latex] (1) -- (2);
\path[draw,thick,->,>=latex] (1) -- (3);
\path[draw,thick,->,>=latex] (1) -- (4);
\path[draw,thick,->,>=latex] (3) -- (4);
\path[draw,thick,->,>=latex] (2) -- (4);
\path[draw,thick,<-,>=latex] (2) -- (5);
\end{tikzpicture}
\end{center}
2017-01-07 15:34:11 +01:00
\subsubsection{Colorings}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\index{coloring}
\index{bipartite graph}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
In a \key{coloring} of a graph,
each node is assigned a color so that
no adjacent nodes have the same color.
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
A graph is \key{bipartite} if
it is possible to color it using two colors.
It turns out that a graph is bipartite
2017-02-04 23:59:31 +01:00
exactly when it does not contain a cycle
with an odd number of edges.
2017-01-07 15:34:11 +01:00
For example, the graph
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$2$};
\node[draw, circle] (2) at (4,3) {$3$};
\node[draw, circle] (3) at (1,1) {$5$};
\node[draw, circle] (4) at (4,1) {$6$};
\node[draw, circle] (5) at (-2,1) {$4$};
\node[draw, circle] (6) at (-2,3) {$1$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (3) -- (4);
\path[draw,thick,-] (2) -- (4);
\path[draw,thick,-] (3) -- (6);
\path[draw,thick,-] (5) -- (6);
\end{tikzpicture}
\end{center}
2017-02-04 23:59:31 +01:00
is bipartite, because it can be colored as follows:
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle, fill=blue!40] (1) at (1,3) {$2$};
\node[draw, circle, fill=red!40] (2) at (4,3) {$3$};
\node[draw, circle, fill=red!40] (3) at (1,1) {$5$};
\node[draw, circle, fill=blue!40] (4) at (4,1) {$6$};
\node[draw, circle, fill=red!40] (5) at (-2,1) {$4$};
\node[draw, circle, fill=blue!40] (6) at (-2,3) {$1$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (3) -- (4);
\path[draw,thick,-] (2) -- (4);
\path[draw,thick,-] (3) -- (6);
\path[draw,thick,-] (5) -- (6);
\end{tikzpicture}
\end{center}
2017-02-17 21:13:30 +01:00
However, the graph
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$2$};
\node[draw, circle] (2) at (4,3) {$3$};
\node[draw, circle] (3) at (1,1) {$5$};
\node[draw, circle] (4) at (4,1) {$6$};
\node[draw, circle] (5) at (-2,1) {$4$};
\node[draw, circle] (6) at (-2,3) {$1$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (3) -- (4);
\path[draw,thick,-] (2) -- (4);
\path[draw,thick,-] (3) -- (6);
\path[draw,thick,-] (5) -- (6);
\path[draw,thick,-] (1) -- (6);
\end{tikzpicture}
\end{center}
is not bipartite, because it is not possible to color
the following cycle of three nodes using two colors:
2017-02-04 23:59:31 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$2$};
\node[draw, circle] (2) at (4,3) {$3$};
\node[draw, circle] (3) at (1,1) {$5$};
\node[draw, circle] (4) at (4,1) {$6$};
\node[draw, circle] (5) at (-2,1) {$4$};
\node[draw, circle] (6) at (-2,3) {$1$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (3) -- (4);
\path[draw,thick,-] (2) -- (4);
\path[draw,thick,-] (3) -- (6);
\path[draw,thick,-] (5) -- (6);
\path[draw,thick,-] (1) -- (6);
2017-02-17 21:13:30 +01:00
\path[draw=red,thick,-,line width=2pt] (1) -- (3);
\path[draw=red,thick,-,line width=2pt] (3) -- (6);
\path[draw=red,thick,-,line width=2pt] (6) -- (1);
2017-02-04 23:59:31 +01:00
\end{tikzpicture}
\end{center}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\subsubsection{Simplicity}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
\index{simple graph}
2016-12-28 23:54:51 +01:00
2017-01-07 15:34:11 +01:00
A graph is \key{simple}
2017-02-04 23:59:31 +01:00
if no edge starts and ends at the same node,
2017-01-07 15:34:11 +01:00
and there are no multiple
edges between two nodes.
2017-02-04 23:59:31 +01:00
Often we assume that graphs are simple.
2017-02-17 21:13:30 +01:00
For example, the following graph is \emph{not} simple:
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$2$};
\node[draw, circle] (2) at (4,3) {$3$};
\node[draw, circle] (3) at (1,1) {$5$};
\node[draw, circle] (4) at (4,1) {$6$};
\node[draw, circle] (5) at (-2,1) {$4$};
\node[draw, circle] (6) at (-2,3) {$1$};
\path[draw,thick,-] (1) edge [bend right=20] (2);
\path[draw,thick,-] (2) edge [bend right=20] (1);
%\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (3) -- (4);
\path[draw,thick,-] (2) -- (4);
\path[draw,thick,-] (3) -- (6);
\path[draw,thick,-] (5) -- (6);
\tikzset{every loop/.style={in=135,out=190}}
\path[draw,thick,-] (5) edge [loop left] (5);
\end{tikzpicture}
\end{center}
2017-01-07 15:57:20 +01:00
\section{Graph representation}
2016-12-28 23:54:51 +01:00
2017-02-04 23:59:31 +01:00
There are several ways to represent graphs
in algorithms.
2017-01-07 15:57:20 +01:00
The choice of a data structure
depends on the size of the graph and
2017-02-04 23:59:31 +01:00
the way the algorithm processes it.
2017-02-17 21:13:30 +01:00
Next we will go through three common representations.
2016-12-28 23:54:51 +01:00
2017-01-07 15:57:20 +01:00
\subsubsection{Adjacency list representation}
2016-12-28 23:54:51 +01:00
2017-01-07 15:57:20 +01:00
\index{adjacency list}
2016-12-28 23:54:51 +01:00
2017-02-04 23:59:31 +01:00
In the adjacency list representation,
each node $x$ in the graph is assigned an \key{adjacency list}
that consists of nodes
to which there is an edge from $x$.
Adjacency lists are the most popular
2017-02-17 21:13:30 +01:00
way to represent graphs, and most algorithms can be
2017-02-04 23:59:31 +01:00
efficiently implemented using them.
2016-12-28 23:54:51 +01:00
2017-02-04 23:59:31 +01:00
A convenient way to store the adjacency lists is to declare
2021-02-08 23:10:42 +01:00
a vector of vectors as follows:
2016-12-28 23:54:51 +01:00
\begin{lstlisting}
2021-02-08 23:10:42 +01:00
vector<vector<int>> g;
2016-12-28 23:54:51 +01:00
\end{lstlisting}
2017-01-07 15:57:20 +01:00
For example, the graph
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
2021-02-08 23:10:42 +01:00
\node[draw, circle] (1) at (1,3) {$0$};
\node[draw, circle] (2) at (3,3) {$1$};
\node[draw, circle] (3) at (5,3) {$2$};
\node[draw, circle] (4) at (3,1) {$3$};
2016-12-28 23:54:51 +01:00
\path[draw,thick,->,>=latex] (1) -- (2);
\path[draw,thick,->,>=latex] (2) -- (3);
\path[draw,thick,->,>=latex] (2) -- (4);
\path[draw,thick,->,>=latex] (3) -- (4);
\path[draw,thick,->,>=latex] (4) -- (1);
\end{tikzpicture}
\end{center}
2017-01-07 15:57:20 +01:00
can be stored as follows:
2016-12-28 23:54:51 +01:00
\begin{lstlisting}
2021-02-08 23:10:42 +01:00
g.assign(4, {}); // g now consists of 4 empty arrays
g[0].push_back(1);
g[1].push_back(2);
g[1].push_back(3);
g[2].push_back(3);
g[3].push_back(0);
2016-12-28 23:54:51 +01:00
\end{lstlisting}
2017-01-07 15:57:20 +01:00
If the graph is undirected, it can be stored in a similar way,
2017-02-17 21:13:30 +01:00
but each edge is added in both directions.
2016-12-28 23:54:51 +01:00
2017-02-04 23:59:31 +01:00
For a weighted graph, the structure can be extended
2017-01-07 15:57:20 +01:00
as follows:
2016-12-28 23:54:51 +01:00
\begin{lstlisting}
2021-02-08 23:10:42 +01:00
vector<vector<pair<int,int>>> g;
2016-12-28 23:54:51 +01:00
\end{lstlisting}
2017-05-28 11:07:31 +02:00
In this case, the adjacency list of node $a$
contains the pair $(b,w)$
always when there is an edge from node $a$ to node $b$
with weight $w$. For example, the graph
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
2021-02-08 23:10:42 +01:00
\node[draw, circle] (1) at (1,3) {$0$};
\node[draw, circle] (2) at (3,3) {$1$};
\node[draw, circle] (3) at (5,3) {$2$};
\node[draw, circle] (4) at (3,1) {$3$};
2016-12-28 23:54:51 +01:00
\path[draw,thick,->,>=latex] (1) -- node[font=\small,label=above:5] {} (2);
\path[draw,thick,->,>=latex] (2) -- node[font=\small,label=above:7] {} (3);
\path[draw,thick,->,>=latex] (2) -- node[font=\small,label=left:6] {} (4);
\path[draw,thick,->,>=latex] (3) -- node[font=\small,label=right:5] {} (4);
\path[draw,thick,->,>=latex] (4) -- node[font=\small,label=left:2] {} (1);
\end{tikzpicture}
\end{center}
2017-01-07 15:57:20 +01:00
can be stored as follows:
2016-12-28 23:54:51 +01:00
\begin{lstlisting}
2021-02-08 23:10:42 +01:00
g.assign(4, {});
g[0].emplace_back(1,5);
g[1].emplace_back(2,7);
g[1].emplace_back(3,6);
g[2].emplace_back(3,5);
g[3].emplace_back(0,2);
2016-12-28 23:54:51 +01:00
\end{lstlisting}
2017-05-07 20:18:56 +02:00
The benefit of using adjacency lists is that
2017-02-04 23:59:31 +01:00
we can efficiently find the nodes to which
2017-02-17 21:13:30 +01:00
we can move from a given node through an edge.
2017-02-04 23:59:31 +01:00
For example, the following loop goes through all nodes
to which we can move from node $s$:
2016-12-28 23:54:51 +01:00
\begin{lstlisting}
2021-02-08 23:10:42 +01:00
for (auto u : g[s]) {
2017-01-07 15:57:20 +01:00
// process node u
2016-12-28 23:54:51 +01:00
}
\end{lstlisting}
2017-01-07 15:57:20 +01:00
\subsubsection{Adjacency matrix representation}
2016-12-28 23:54:51 +01:00
2017-01-07 15:57:20 +01:00
\index{adjacency matrix}
2016-12-28 23:54:51 +01:00
2017-01-07 15:57:20 +01:00
An \key{adjacency matrix} is a two-dimensional array
2017-02-17 21:13:30 +01:00
that indicates which edges the graph contains.
2017-02-04 23:59:31 +01:00
We can efficiently check from an adjacency matrix
2017-01-07 15:57:20 +01:00
if there is an edge between two nodes.
2017-02-04 23:59:31 +01:00
The matrix can be stored as an array
2016-12-28 23:54:51 +01:00
\begin{lstlisting}
2021-02-08 23:10:42 +01:00
vector<vector<int>> adj;
adj.assign(n, vector<int>(n, 0));
2016-12-28 23:54:51 +01:00
\end{lstlisting}
2017-05-28 11:07:31 +02:00
where each value $\texttt{adj}[a][b]$ indicates
2017-01-07 15:57:20 +01:00
whether the graph contains an edge from
node $a$ to node $b$.
If the edge is included in the graph,
2017-05-28 11:07:31 +02:00
then $\texttt{adj}[a][b]=1$,
and otherwise $\texttt{adj}[a][b]=0$.
2017-01-07 15:57:20 +01:00
For example, the graph
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
2021-02-08 23:10:42 +01:00
\node[draw, circle] (1) at (1,3) {$0$};
\node[draw, circle] (2) at (3,3) {$1$};
\node[draw, circle] (3) at (5,3) {$2$};
\node[draw, circle] (4) at (3,1) {$3$};
2016-12-28 23:54:51 +01:00
\path[draw,thick,->,>=latex] (1) -- (2);
\path[draw,thick,->,>=latex] (2) -- (3);
\path[draw,thick,->,>=latex] (2) -- (4);
\path[draw,thick,->,>=latex] (3) -- (4);
\path[draw,thick,->,>=latex] (4) -- (1);
\end{tikzpicture}
\end{center}
2017-01-07 15:57:20 +01:00
can be represented as follows:
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.7]
\draw (0,0) grid (4,4);
\node at (0.5,0.5) {1};
\node at (1.5,0.5) {0};
\node at (2.5,0.5) {0};
\node at (3.5,0.5) {0};
\node at (0.5,1.5) {0};
\node at (1.5,1.5) {0};
\node at (2.5,1.5) {0};
\node at (3.5,1.5) {1};
\node at (0.5,2.5) {0};
\node at (1.5,2.5) {0};
\node at (2.5,2.5) {1};
\node at (3.5,2.5) {1};
\node at (0.5,3.5) {0};
\node at (1.5,3.5) {1};
\node at (2.5,3.5) {0};
\node at (3.5,3.5) {0};
\node at (-0.5,0.5) {4};
\node at (-0.5,1.5) {3};
\node at (-0.5,2.5) {2};
\node at (-0.5,3.5) {1};
\node at (0.5,4.5) {1};
\node at (1.5,4.5) {2};
\node at (2.5,4.5) {3};
\node at (3.5,4.5) {4};
\end{tikzpicture}
\end{center}
2017-03-07 17:54:41 +01:00
If the graph is weighted, the adjacency matrix
2017-01-07 15:57:20 +01:00
representation can be extended so that
the matrix contains the weight of the edge
if the edge exists.
Using this representation, the graph
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {$1$};
\node[draw, circle] (2) at (3,3) {$2$};
\node[draw, circle] (3) at (5,3) {$3$};
\node[draw, circle] (4) at (3,1) {$4$};
\path[draw,thick,->,>=latex] (1) -- node[font=\small,label=above:5] {} (2);
\path[draw,thick,->,>=latex] (2) -- node[font=\small,label=above:7] {} (3);
\path[draw,thick,->,>=latex] (2) -- node[font=\small,label=left:6] {} (4);
\path[draw,thick,->,>=latex] (3) -- node[font=\small,label=right:5] {} (4);
\path[draw,thick,->,>=latex] (4) -- node[font=\small,label=left:2] {} (1);
\end{tikzpicture}
\end{center}
\begin{samepage}
2017-01-07 15:57:20 +01:00
corresponds to the following matrix:
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.7]
\draw (0,0) grid (4,4);
\node at (0.5,0.5) {2};
\node at (1.5,0.5) {0};
\node at (2.5,0.5) {0};
\node at (3.5,0.5) {0};
\node at (0.5,1.5) {0};
\node at (1.5,1.5) {0};
\node at (2.5,1.5) {0};
\node at (3.5,1.5) {5};
\node at (0.5,2.5) {0};
\node at (1.5,2.5) {0};
\node at (2.5,2.5) {7};
\node at (3.5,2.5) {6};
\node at (0.5,3.5) {0};
\node at (1.5,3.5) {5};
\node at (2.5,3.5) {0};
\node at (3.5,3.5) {0};
\node at (-0.5,0.5) {4};
\node at (-0.5,1.5) {3};
\node at (-0.5,2.5) {2};
\node at (-0.5,3.5) {1};
\node at (0.5,4.5) {1};
\node at (1.5,4.5) {2};
\node at (2.5,4.5) {3};
\node at (3.5,4.5) {4};
\end{tikzpicture}
\end{center}
\end{samepage}
2017-05-07 20:18:56 +02:00
The drawback of the adjacency matrix representation
2017-05-28 11:07:31 +02:00
is that the matrix contains $n^2$ elements,
2017-02-04 23:59:31 +01:00
and usually most of them are zero.
For this reason, the representation cannot be used
if the graph is large.
2017-01-07 15:57:20 +01:00
\subsubsection{Edge list representation}
2016-12-28 23:54:51 +01:00
2017-01-07 15:57:20 +01:00
\index{edge list}
2016-12-28 23:54:51 +01:00
2017-02-04 23:59:31 +01:00
An \key{edge list} contains all edges of a graph
in some order.
This is a convenient way to represent a graph
2017-02-17 21:13:30 +01:00
if the algorithm processes all edges of the graph
2017-02-04 23:59:31 +01:00
and it is not needed to find edges that start
2017-01-07 15:57:20 +01:00
at a given node.
2016-12-28 23:54:51 +01:00
2017-01-07 15:57:20 +01:00
The edge list can be stored in a vector
2016-12-28 23:54:51 +01:00
\begin{lstlisting}
vector<pair<int,int>> edges;
2016-12-28 23:54:51 +01:00
\end{lstlisting}
2017-02-04 23:59:31 +01:00
where each pair $(a,b)$ denotes that
there is an edge from node $a$ to node $b$.
2017-01-07 15:57:20 +01:00
Thus, the graph
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
2021-02-08 23:10:42 +01:00
\node[draw, circle] (1) at (1,3) {$0$};
\node[draw, circle] (2) at (3,3) {$1$};
\node[draw, circle] (3) at (5,3) {$2$};
\node[draw, circle] (4) at (3,1) {$3$};
2016-12-28 23:54:51 +01:00
\path[draw,thick,->,>=latex] (1) -- (2);
\path[draw,thick,->,>=latex] (2) -- (3);
\path[draw,thick,->,>=latex] (2) -- (4);
\path[draw,thick,->,>=latex] (3) -- (4);
\path[draw,thick,->,>=latex] (4) -- (1);
\end{tikzpicture}
\end{center}
2017-01-07 15:57:20 +01:00
can be represented as follows:
2016-12-28 23:54:51 +01:00
\begin{lstlisting}
edges.emplace_back(0,2);
edges.emplace_back(1,3);
edges.emplace_back(1,4);
edges.emplace_back(2,4);
edges.emplace_back(3,1);
2016-12-28 23:54:51 +01:00
\end{lstlisting}
\noindent
2017-02-04 23:59:31 +01:00
If the graph is weighted, the structure can
be extended as follows:
2016-12-28 23:54:51 +01:00
\begin{lstlisting}
vector<tuple<int,int,int>> edges;
2016-12-28 23:54:51 +01:00
\end{lstlisting}
2017-02-04 23:59:31 +01:00
Each element in this list is of the
form $(a,b,w)$, which means that there
is an edge from node $a$ to node $b$ with weight $w$.
2017-01-07 15:57:20 +01:00
For example, the graph
2016-12-28 23:54:51 +01:00
\begin{center}
\begin{tikzpicture}[scale=0.9]
2021-02-08 23:10:42 +01:00
\node[draw, circle] (1) at (1,3) {$0$};
\node[draw, circle] (2) at (3,3) {$1$};
\node[draw, circle] (3) at (5,3) {$2$};
\node[draw, circle] (4) at (3,1) {$3$};
2016-12-28 23:54:51 +01:00
\path[draw,thick,->,>=latex] (1) -- node[font=\small,label=above:5] {} (2);
\path[draw,thick,->,>=latex] (2) -- node[font=\small,label=above:7] {} (3);
\path[draw,thick,->,>=latex] (2) -- node[font=\small,label=left:6] {} (4);
\path[draw,thick,->,>=latex] (3) -- node[font=\small,label=right:5] {} (4);
\path[draw,thick,->,>=latex] (4) -- node[font=\small,label=left:2] {} (1);
\end{tikzpicture}
\end{center}
\begin{samepage}
can be represented as follows\footnote{Instead of \texttt{emplace\_back(0,2,5)},
one could also write \texttt{edges.push\_back(\{0,2,5\})} or
\texttt{edges.push\_back(make\_tuple(0,2,5))}, however, using \texttt{emplace\_back} is generally preferred.}:
2016-12-28 23:54:51 +01:00
\begin{lstlisting}
edges.emplace_back(0,2,5);
edges.emplace_back(1,3,7);
edges.emplace_back(1,4,6);
edges.emplace_back(2,4,5);
edges.emplace_back(3,1,2);
2016-12-28 23:54:51 +01:00
\end{lstlisting}
2017-03-07 17:54:41 +01:00
\end{samepage}