Small fixes

This commit is contained in:
Antti H S Laaksonen 2017-05-28 12:07:31 +03:00
parent 1ee57c911b
commit 7eb756088f
3 changed files with 56 additions and 54 deletions

View File

@ -57,6 +57,7 @@ The \key{length} of a path is the number of
edges in it. edges in it.
For example, the above graph contains For example, the above graph contains
a path $1 \rightarrow 3 \rightarrow 4 \rightarrow 5$ a path $1 \rightarrow 3 \rightarrow 4 \rightarrow 5$
of length 3
from node 1 to node 5: from node 1 to node 5:
\begin{center} \begin{center}
@ -519,10 +520,10 @@ as follows:
vector<pair<int,int>> adj[N]; vector<pair<int,int>> adj[N];
\end{lstlisting} \end{lstlisting}
If there is an edge from node $a$ to node $b$ In this case, the adjacency list of node $a$
with weight $w$, the adjacency list of node $a$ contains the pair $(b,w)$
contains the pair $(b,w)$. always when there is an edge from node $a$ to node $b$
For example, the graph with weight $w$. For example, the graph
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.9] \begin{tikzpicture}[scale=0.9]
@ -569,14 +570,14 @@ We can efficiently check from an adjacency matrix
if there is an edge between two nodes. if there is an edge between two nodes.
The matrix can be stored as an array The matrix can be stored as an array
\begin{lstlisting} \begin{lstlisting}
int mat[N][N]; int adj[N][N];
\end{lstlisting} \end{lstlisting}
where each value $\texttt{mat}[a][b]$ indicates where each value $\texttt{adj}[a][b]$ indicates
whether the graph contains an edge from whether the graph contains an edge from
node $a$ to node $b$. node $a$ to node $b$.
If the edge is included in the graph, If the edge is included in the graph,
then $\texttt{mat}[a][b]=1$, then $\texttt{adj}[a][b]=1$,
and otherwise $\texttt{mat}[a][b]=0$. and otherwise $\texttt{adj}[a][b]=0$.
For example, the graph For example, the graph
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.9] \begin{tikzpicture}[scale=0.9]
@ -677,7 +678,7 @@ corresponds to the following matrix:
\end{samepage} \end{samepage}
The drawback of the adjacency matrix representation The drawback of the adjacency matrix representation
is that there are $n^2$ elements in the matrix is that the matrix contains $n^2$ elements,
and usually most of them are zero. and usually most of them are zero.
For this reason, the representation cannot be used For this reason, the representation cannot be used
if the graph is large. if the graph is large.

View File

@ -133,17 +133,17 @@ vector<int> adj[N];
\end{lstlisting} \end{lstlisting}
and also maintains an array and also maintains an array
\begin{lstlisting} \begin{lstlisting}
bool vis[N]; bool visited[N];
\end{lstlisting} \end{lstlisting}
that keeps track of the visited nodes. that keeps track of the visited nodes.
Initially, each array value is \texttt{false}, Initially, each array value is \texttt{false},
and when the search arrives at node $s$, and when the search arrives at node $s$,
the value of \texttt{vis}[$s$] becomes \texttt{true}. the value of \texttt{visited}[$s$] becomes \texttt{true}.
The function can be implemented as follows: The function can be implemented as follows:
\begin{lstlisting} \begin{lstlisting}
void dfs(int s) { void dfs(int s) {
if (vis[s]) return; if (visited[s]) return;
vis[s] = true; visited[s] = true;
// process node s // process node s
for (auto u: adj[s]) { for (auto u: adj[s]) {
dfs(u); dfs(u);
@ -312,8 +312,8 @@ as adjacency lists and maintains the following
data structures: data structures:
\begin{lstlisting} \begin{lstlisting}
queue<int> q; queue<int> q;
bool vis[N]; bool visited[N];
int dist[N]; int distance[N];
\end{lstlisting} \end{lstlisting}
The queue \texttt{q} The queue \texttt{q}
@ -322,24 +322,24 @@ in increasing order of their distance.
New nodes are always added to the end New nodes are always added to the end
of the queue, and the node at the beginning of the queue, and the node at the beginning
of the queue is the next node to be processed. of the queue is the next node to be processed.
The array \texttt{vis} indicates The array \texttt{visited} indicates
which nodes the search has already visited, which nodes the search has already visited,
and the array \texttt{dist} will contain the and the array \texttt{distance} will contain the
distances from the starting node to all nodes of the graph. distances from the starting node to all nodes of the graph.
The search can be implemented as follows, The search can be implemented as follows,
starting at node $x$: starting at node $x$:
\begin{lstlisting} \begin{lstlisting}
vis[x] = true; visited[x] = true;
dist[x] = 0; distance[x] = 0;
q.push(x); q.push(x);
while (!q.empty()) { while (!q.empty()) {
int s = q.front(); q.pop(); int s = q.front(); q.pop();
// process node s // process node s
for (auto u : adj[s]) { for (auto u : adj[s]) {
if (vis[u]) continue; if (visited[u]) continue;
vis[u] = true; visited[u] = true;
dist[u] = dist[s]+1; distance[u] = distance[s]+1;
q.push(u); q.push(u);
} }
} }

View File

@ -202,19 +202,19 @@ The algorithm consists of $n-1$ rounds,
and on each round the algorithm goes through and on each round the algorithm goes through
all edges of the graph and tries to all edges of the graph and tries to
reduce the distances. reduce the distances.
The algorithm constructs an array \texttt{dist} The algorithm constructs an array \texttt{distance}
that will contain the distances from $x$ that will contain the distances from $x$
to all nodes of the graph. to all nodes of the graph.
The constant \texttt{INF} denotes an infinite distance. The constant \texttt{INF} denotes an infinite distance.
\begin{lstlisting} \begin{lstlisting}
for (int i = 1; i <= n; i++) dist[i] = INF; for (int i = 1; i <= n; i++) distance[i] = INF;
dist[x] = 0; distance[x] = 0;
for (int i = 1; i <= n-1; i++) { for (int i = 1; i <= n-1; i++) {
for (auto e : edges) { for (auto e : edges) {
int a, b, w; int a, b, w;
tie(a, b, w) = e; tie(a, b, w) = e;
dist[b] = min(dist[b], dist[a]+w); distance[b] = min(distance[b], distance[a]+w);
} }
} }
\end{lstlisting} \end{lstlisting}
@ -419,7 +419,8 @@ In this case,
the edges from node 1 reduced the distances of the edges from node 1 reduced the distances of
nodes 2, 4 and 5, whose distances are now 5, 9 and 1. nodes 2, 4 and 5, whose distances are now 5, 9 and 1.
The next node to be processed is node 5 with distance 1: The next node to be processed is node 5 with distance 1.
This reduces the distance to node 4 from 9 to 3:
\begin{center} \begin{center}
\begin{tikzpicture} \begin{tikzpicture}
\node[draw, circle] (1) at (1,3) {3}; \node[draw, circle] (1) at (1,3) {3};
@ -444,7 +445,8 @@ The next node to be processed is node 5 with distance 1:
\path[draw=red,thick,->,line width=2pt] (5) -- (2); \path[draw=red,thick,->,line width=2pt] (5) -- (2);
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
After this, the next node is node 4: After this, the next node is node 4, which reduces
the distance to node 3 to 9:
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.9] \begin{tikzpicture}[scale=0.9]
\node[draw, circle] (1) at (1,3) {3}; \node[draw, circle] (1) at (1,3) {3};
@ -553,28 +555,27 @@ that contains the nodes ordered by their distances.
Using a priority queue, the next node to be processed Using a priority queue, the next node to be processed
can be retrieved in logarithmic time. can be retrieved in logarithmic time.
In the following code, In the following code, the priority queue
the priority queue
\texttt{q} contains pairs of the form $(-d,x)$, \texttt{q} contains pairs of the form $(-d,x)$,
meaning that the current distance to node $x$ is $d$. meaning that the current distance to node $x$ is $d$.
The array $\texttt{dist}$ contains the distance to The array $\texttt{distance}$ contains the distance to
each node, and the array $\texttt{ready}$ indicates each node, and the array $\texttt{processed}$ indicates
whether a node has been processed. whether a node has been processed.
Initially the distance is $0$ to $x$ and $\infty$ to all other nodes. Initially the distance is $0$ to $x$ and $\infty$ to all other nodes.
\begin{lstlisting} \begin{lstlisting}
for (int i = 1; i <= n; i++) dist[i] = INF; for (int i = 1; i <= n; i++) distance[i] = INF;
dist[x] = 0; distance[x] = 0;
q.push({0,x}); q.push({0,x});
while (!q.empty()) { while (!q.empty()) {
int a = q.top().second; q.pop(); int a = q.top().second; q.pop();
if (ready[a]) continue; if (processed[a]) continue;
ready[a] = true; processed[a] = true;
for (auto u : v[a]) { for (auto u : adj[a]) {
int b = u.first, w = u.second; int b = u.first, w = u.second;
if (dist[a]+w < dist[b]) { if (distance[a]+w < distance[b]) {
dist[b] = dist[a]+w; distance[b] = distance[a]+w;
q.push({-dist[b],b}); q.push({-distance[b],b});
} }
} }
} }
@ -586,7 +587,7 @@ The reason for this is that the
default version of the C++ priority queue finds maximum default version of the C++ priority queue finds maximum
elements, while we want to find minimum elements. elements, while we want to find minimum elements.
By using negative distances, By using negative distances,
we can directly use the default version of the C++ priority queue\footnote{Of we can directly use the default priority queue\footnote{Of
course, we could also declare the priority queue as in Chapter 4.5 course, we could also declare the priority queue as in Chapter 4.5
and use positive distances, but the implementation would be a bit longer.}. and use positive distances, but the implementation would be a bit longer.}.
Also note that there may be several instances of the same Also note that there may be several instances of the same
@ -613,10 +614,10 @@ in a single run.
The algorithm maintains a two-dimensional array The algorithm maintains a two-dimensional array
that contains distances between the nodes. that contains distances between the nodes.
First, the distances are calculated only using First, distances are calculated only using
direct edges between the nodes. direct edges between the nodes,
After this the algorithm reduces the distances and after this, the algorithm reduces distances
by using intermediate nodes in the paths. by using intermediate nodes in paths.
\subsubsection{Example} \subsubsection{Example}
@ -661,8 +662,7 @@ In this graph, the initial array is as follows:
The algorithm consists of consecutive rounds. The algorithm consists of consecutive rounds.
On each round, the algorithm selects a new node On each round, the algorithm selects a new node
that can act as an intermediate node in paths from now on, that can act as an intermediate node in paths from now on,
and the algorithm reduces the distances in the array and distances are reduced using this node.
using this node.
On the first round, node 1 is the new intermediate node. On the first round, node 1 is the new intermediate node.
There is a new path between nodes 2 and 4 There is a new path between nodes 2 and 4
@ -764,17 +764,17 @@ The advantage of the
FloydWarshall algorithm that it is FloydWarshall algorithm that it is
easy to implement. easy to implement.
The following code constructs a The following code constructs a
distance matrix where $\texttt{dist}[a][b]$ distance matrix where $\texttt{distance}[a][b]$
is the shortest distance between nodes $a$ and $b$. is the shortest distance between nodes $a$ and $b$.
First, the algorithm initializes \texttt{dist} First, the algorithm initializes \texttt{distance}
using the adjacency matrix \texttt{mat} of the graph: using the adjacency matrix \texttt{adj} of the graph:
\begin{lstlisting} \begin{lstlisting}
for (int i = 1; i <= n; i++) { for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) { for (int j = 1; j <= n; j++) {
if (i == j) dist[i][j] = 0; if (i == j) distance[i][j] = 0;
else if (mat[i][j]) dist[i][j] = mat[i][j]; else if (adj[i][j]) distance[i][j] = adj[i][j];
else dist[i][j] = INF; else distance[i][j] = INF;
} }
} }
\end{lstlisting} \end{lstlisting}
@ -783,7 +783,8 @@ After this, the shortest distances can be found as follows:
for (int k = 1; k <= n; k++) { for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) { for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) { for (int j = 1; j <= n; j++) {
dist[i][j] = min(dist[i][j], dist[i][k]+dist[k][j]); distance[i][j] = min(distance[i][j],
distance[i][k]+distance[k][j]);
} }
} }
} }