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
|
|
|
|
interpreting the problem as a graph problem
|
|
|
|
and using a suitable graph algorithm.
|
|
|
|
A typical example of a graph is a network
|
|
|
|
of roads and cities in a country.
|
|
|
|
Sometimes, though, the graph is hidden
|
|
|
|
in the problem and it can be difficult to detect it.
|
|
|
|
|
|
|
|
This part of the book discusses techniques and algorithms
|
|
|
|
involving graphs
|
|
|
|
that are important in competitive programming.
|
|
|
|
We will first go through graph terminology
|
|
|
|
and different ways to store graphs in algorithms.
|
|
|
|
|
|
|
|
\section{Terminology}
|
|
|
|
|
|
|
|
\index{graph}
|
|
|
|
\index{node}
|
|
|
|
\index{edge}
|
|
|
|
|
|
|
|
A \key{graph} consists of \key{nodes}
|
|
|
|
and \key{edges} between them.
|
|
|
|
In this book,
|
|
|
|
the variable $n$ denotes the number of nodes
|
|
|
|
in a graph, and the variable $m$ denotes
|
|
|
|
the number of edges.
|
|
|
|
In addition, the nodes are numbered
|
|
|
|
using integers $1,2,\ldots,n$.
|
|
|
|
|
|
|
|
For example, the following graph contains 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
|
|
|
|
2017-01-07 15:34:11 +01:00
|
|
|
A \key{path} is a route from node $a$ to node $b$
|
|
|
|
that goes through the edges in the graph.
|
|
|
|
The \key{length} of a path is the number of
|
|
|
|
edges in the path.
|
|
|
|
For example, in the above graph, paths
|
|
|
|
from node 1 to node 5 are:
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
|
|
\begin{itemize}
|
2017-01-07 15:34:11 +01:00
|
|
|
\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)
|
2016-12-28 23:54:51 +01:00
|
|
|
\end{itemize}
|
|
|
|
|
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-01-07 15:34:11 +01:00
|
|
|
A graph is \key{connected}, if there is path
|
|
|
|
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-01-07 15:34:11 +01:00
|
|
|
The following graph is not connected
|
|
|
|
because it is not possible to get to other
|
|
|
|
nodes from node 4.
|
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-01-07 15:34:11 +01:00
|
|
|
\index{compomnent}
|
|
|
|
|
|
|
|
The connected parts of a graph are
|
|
|
|
its \key{components}.
|
|
|
|
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
|
|
|
|
that contains $n$ nodes and $n-1$ edges.
|
|
|
|
In a tree, there is a unique path
|
|
|
|
between any two nodes.
|
|
|
|
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}
|
|
|
|
if the edges can be travelled only
|
|
|
|
in one direction.
|
|
|
|
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-01-07 15:34:11 +01:00
|
|
|
The above graph contains a path from
|
|
|
|
node $3$ to $5$ using edges
|
2016-12-28 23:54:51 +01:00
|
|
|
$3 \rightarrow 1 \rightarrow 2 \rightarrow 5$.
|
2017-01-07 15:34:11 +01:00
|
|
|
However, the graph doesn't contain
|
|
|
|
a path from node $5$ to $3$.
|
2016-12-28 23:54:51 +01:00
|
|
|
|
2017-01-07 15:34:11 +01:00
|
|
|
\index{cycle}
|
|
|
|
\index{acyclic graph}
|
2016-12-28 23:54:51 +01:00
|
|
|
|
2017-01-07 15:34:11 +01:00
|
|
|
A \key{cycle} is a path whose first and
|
|
|
|
last node is the same.
|
|
|
|
For example, the above graph contains
|
|
|
|
a cycle
|
2016-12-28 23:54:51 +01:00
|
|
|
$1 \rightarrow 2 \rightarrow 4 \rightarrow 1$.
|
2017-01-07 15:34:11 +01:00
|
|
|
If a graph doesn't contain any cycles,
|
|
|
|
it is called \key{acyclic}.
|
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}.
|
|
|
|
Often, the weights are interpreted as edge lengths.
|
|
|
|
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-01-07 15:34:11 +01:00
|
|
|
Now the length of a path is the sum of
|
|
|
|
edge weights.
|
|
|
|
For example, in the above graph
|
|
|
|
the length of path
|
|
|
|
$1 \rightarrow 2 \rightarrow 5$
|
|
|
|
is $12$, and the length of path
|
|
|
|
$1 \rightarrow 3 \rightarrow 4 \rightarrow 5$ is $11$.
|
|
|
|
The latter is the 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}
|
|
|
|
if there is a edge between them.
|
|
|
|
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-01-07 15:34:11 +01:00
|
|
|
The sum of degrees in a graph is always $2m$
|
|
|
|
where $m$ is the number of edges.
|
|
|
|
The reason for this is that each edge
|
|
|
|
increases the degree of two nodes by one.
|
|
|
|
Thus, 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}
|
|
|
|
and \key{outdegree} of a node is
|
|
|
|
the number of edges that end and begin
|
|
|
|
at the node, respectively.
|
|
|
|
For example, in the following graph,
|
|
|
|
node 2 has indegree 2 and outdegree 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
|
|
|
|
exactly when it doesn't contain a cycle
|
|
|
|
with odd number of edges.
|
|
|
|
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-01-07 15:34:11 +01:00
|
|
|
is bipartite because we can color it 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-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}
|
|
|
|
if no edge begins and ends at the same node,
|
|
|
|
and there are no multiple
|
|
|
|
edges between two nodes.
|
|
|
|
Often we will assume that the graph is simple.
|
|
|
|
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) 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:34:11 +01:00
|
|
|
is \emph{not} simple because there is an edge that begins
|
|
|
|
and ends at node 4, and there are two edges
|
|
|
|
between nodes 2 and 3.
|
2016-12-28 23:54:51 +01:00
|
|
|
|
|
|
|
\section{Verkko muistissa}
|
|
|
|
|
|
|
|
On monia tapoja pitää verkkoa muistissa algoritmissa.
|
|
|
|
Sopiva tietorakenne riippuu siitä,
|
|
|
|
kuinka suuri verkko on ja
|
|
|
|
millä tavoin algoritmi käsittelee sitä.
|
|
|
|
Seuraavaksi käymme läpi kolme tavallista vaihtoehtoa.
|
|
|
|
|
|
|
|
\subsubsection{Vieruslistaesitys}
|
|
|
|
|
|
|
|
\index{vieruslista@vieruslista}
|
|
|
|
|
|
|
|
Tavallisin tapa pitää verkkoa muistissa on
|
|
|
|
luoda jokaisesta solmusta \key{vieruslista},
|
|
|
|
joka sisältää kaikki solmut,
|
|
|
|
joihin solmusta pystyy siirtymään kaarta pitkin.
|
|
|
|
Vieruslistaesitys on tavallisin verkon esitysmuoto, ja
|
|
|
|
useimmat algoritmit pystyy toteuttamaan
|
|
|
|
tehokkaasti sitä käyttäen.
|
|
|
|
|
|
|
|
Kätevä tapa tallentaa verkon vieruslistaesitys on luoda taulukko,
|
|
|
|
jossa jokainen alkio on vektori:
|
|
|
|
\begin{lstlisting}
|
|
|
|
vector<int> v[N];
|
|
|
|
\end{lstlisting}
|
|
|
|
|
|
|
|
Taulukossa solmun $s$ vieruslista on kohdassa $\texttt{v}[s]$.
|
|
|
|
Vakio $N$ on valittu niin suureksi,
|
|
|
|
että kaikki vieruslistat mahtuvat taulukkoon.
|
|
|
|
Esimerkiksi verkon
|
|
|
|
|
|
|
|
\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) -- (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}
|
|
|
|
voi tallentaa seuraavasti:
|
|
|
|
\begin{lstlisting}
|
|
|
|
v[1].push_back(2);
|
|
|
|
v[2].push_back(3);
|
|
|
|
v[2].push_back(4);
|
|
|
|
v[3].push_back(4);
|
|
|
|
v[4].push_back(1);
|
|
|
|
\end{lstlisting}
|
|
|
|
|
|
|
|
Jos verkko on suuntaamaton, sen voi tallentaa samalla tavalla,
|
|
|
|
mutta silloin jokainen kaari lisätään kumpaankin suuntaan.
|
|
|
|
|
|
|
|
Painotetun verkon tapauksessa rakennetta voi laajentaa näin:
|
|
|
|
|
|
|
|
\begin{lstlisting}
|
|
|
|
vector<pair<int,int>> v[N];
|
|
|
|
\end{lstlisting}
|
|
|
|
|
|
|
|
Nyt vieruslistalla on pareja, joiden ensimmäinen kenttä on
|
|
|
|
kaaren kohdesolmu ja toinen kenttä on kaaren paino.
|
|
|
|
Esimerkiksi verkon
|
|
|
|
|
|
|
|
\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}
|
|
|
|
voi tallentaa seuraavasti:
|
|
|
|
\begin{lstlisting}
|
|
|
|
v[1].push_back({2,5});
|
|
|
|
v[2].push_back({3,7});
|
|
|
|
v[2].push_back({4,6});
|
|
|
|
v[3].push_back({4,5});
|
|
|
|
v[4].push_back({1,2});
|
|
|
|
\end{lstlisting}
|
|
|
|
|
|
|
|
Vieruslistaesityksen etuna on, että sen avulla on nopeaa selvittää,
|
|
|
|
mihin solmuihin tietystä solmusta pääsee kulkemaan.
|
|
|
|
Esimerkiksi seuraava silmukka käy läpi kaikki solmut,
|
|
|
|
joihin pääsee solmusta $s$:
|
|
|
|
|
|
|
|
\begin{lstlisting}
|
|
|
|
for (auto u : v[s]) {
|
|
|
|
// käsittele solmu u
|
|
|
|
}
|
|
|
|
\end{lstlisting}
|
|
|
|
|
|
|
|
\subsubsection{Vierusmatriisiesitys}
|
|
|
|
|
|
|
|
\index{vierusmatriisi@vierusmatriisi}
|
|
|
|
|
|
|
|
\key{Vierusmatriisi} on kaksiulotteinen taulukko,
|
|
|
|
joka kertoo jokaisesta mahdollisesta kaaresta,
|
|
|
|
onko se mukana verkossa.
|
|
|
|
Vierusmatriisista on nopeaa tarkistaa,
|
|
|
|
onko kahden solmun välillä kaari.
|
|
|
|
Toisaalta matriisi vie paljon tilaa,
|
|
|
|
jos verkko on suuri.
|
|
|
|
Vierusmatriisi tallennetaan taulukkona
|
|
|
|
|
|
|
|
\begin{lstlisting}
|
|
|
|
int v[N][N];
|
|
|
|
\end{lstlisting}
|
|
|
|
|
|
|
|
jossa arvo $\texttt{v}[a][b]$ ilmaisee,
|
|
|
|
onko kaari solmusta $a$ solmuun $b$ mukana verkossa.
|
|
|
|
Jos kaari on mukana verkossa,
|
|
|
|
niin $\texttt{v}[a][b]=1$,
|
|
|
|
ja muussa tapauksessa $\texttt{v}[a][b]=0$.
|
|
|
|
Nyt esimerkiksi verkkoa
|
|
|
|
\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) -- (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}
|
|
|
|
vastaa seuraava vierusmatriisi:
|
|
|
|
\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}
|
|
|
|
|
|
|
|
Jos verkko on painotettu, vierusmatriisiesitystä voi
|
|
|
|
laajentaa luontevasti niin, että matriisissa kerrotaan
|
|
|
|
kaaren paino, jos kaari on olemassa.
|
|
|
|
Tätä esitystapaa käyttäen esimerkiksi verkkoa
|
|
|
|
|
|
|
|
\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}
|
|
|
|
vastaa seuraava vierusmatriisi:
|
|
|
|
\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}
|
|
|
|
|
|
|
|
\subsubsection{Kaarilistaesitys}
|
|
|
|
|
|
|
|
\index{kaarilista@kaarilista}
|
|
|
|
|
|
|
|
\key{Kaarilista} sisältää kaikki verkon kaaret.
|
|
|
|
Kaarilista on hyvä tapa tallentaa verkko,
|
|
|
|
jos algoritmissa täytyy käydä läpi
|
|
|
|
kaikki verkon kaaret eikä ole tarvetta
|
|
|
|
etsiä kaarta alkusolmun perusteella.
|
|
|
|
|
|
|
|
Kaarilistan voi tallentaa vektoriin
|
|
|
|
\begin{lstlisting}
|
|
|
|
vector<pair<int,int>> v;
|
|
|
|
\end{lstlisting}
|
|
|
|
jossa jokaisessa solmussa on parina kaaren
|
|
|
|
alku- ja loppusolmu.
|
|
|
|
Tällöin esimerkiksi verkon
|
|
|
|
|
|
|
|
\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) -- (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}
|
|
|
|
voi tallentaa seuraavasti:
|
|
|
|
\begin{lstlisting}
|
|
|
|
v.push_back({1,2});
|
|
|
|
v.push_back({2,3});
|
|
|
|
v.push_back({2,4});
|
|
|
|
v.push_back({3,4});
|
|
|
|
v.push_back({4,1});
|
|
|
|
\end{lstlisting}
|
|
|
|
|
|
|
|
\noindent
|
|
|
|
Painotetun verkon tapauksessa rakennetta voi laajentaa
|
|
|
|
esimerkiksi näin:
|
|
|
|
\begin{lstlisting}
|
|
|
|
vector<pair<pair<int,int>,int>> v;
|
|
|
|
\end{lstlisting}
|
|
|
|
Nyt listalla on pareja, joiden ensimmäinen jäsen
|
|
|
|
sisältää parina kaaren alku- ja loppusolmun,
|
|
|
|
ja toinen jäsen on kaaren paino.
|
|
|
|
Esimerkiksi verkon
|
|
|
|
|
|
|
|
\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}
|
|
|
|
voi tallentaa seuraavasti:
|
|
|
|
\begin{lstlisting}
|
|
|
|
v.push_back({{1,2},5});
|
|
|
|
v.push_back({{2,3},7});
|
|
|
|
v.push_back({{2,4},6});
|
|
|
|
v.push_back({{3,4},5});
|
|
|
|
v.push_back({{4,1},2});
|
|
|
|
\end{lstlisting}
|
|
|
|
\end{samepage}
|