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.
For example, the above graph contains
a path $1 \rightarrow 3 \rightarrow 4 \rightarrow 5$
of length 3
from node 1 to node 5:
\begin{center}
@ -519,10 +520,10 @@ as follows:
vector<pair<int,int>> adj[N];
\end{lstlisting}
If there is an edge from node $a$ to node $b$
with weight $w$, the adjacency list of node $a$
contains the pair $(b,w)$.
For example, the graph
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
\begin{center}
\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.
The matrix can be stored as an array
\begin{lstlisting}
int mat[N][N];
int adj[N][N];
\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
node $a$ to node $b$.
If the edge is included in the graph,
then $\texttt{mat}[a][b]=1$,
and otherwise $\texttt{mat}[a][b]=0$.
then $\texttt{adj}[a][b]=1$,
and otherwise $\texttt{adj}[a][b]=0$.
For example, the graph
\begin{center}
\begin{tikzpicture}[scale=0.9]
@ -677,7 +678,7 @@ corresponds to the following matrix:
\end{samepage}
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.
For this reason, the representation cannot be used
if the graph is large.

View File

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

View File

@ -202,19 +202,19 @@ The algorithm consists of $n-1$ rounds,
and on each round the algorithm goes through
all edges of the graph and tries to
reduce the distances.
The algorithm constructs an array \texttt{dist}
The algorithm constructs an array \texttt{distance}
that will contain the distances from $x$
to all nodes of the graph.
The constant \texttt{INF} denotes an infinite distance.
\begin{lstlisting}
for (int i = 1; i <= n; i++) dist[i] = INF;
dist[x] = 0;
for (int i = 1; i <= n; i++) distance[i] = INF;
distance[x] = 0;
for (int i = 1; i <= n-1; i++) {
for (auto e : edges) {
int a, b, w;
tie(a, b, w) = e;
dist[b] = min(dist[b], dist[a]+w);
distance[b] = min(distance[b], distance[a]+w);
}
}
\end{lstlisting}
@ -419,7 +419,8 @@ In this case,
the edges from node 1 reduced the distances of
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{tikzpicture}
\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);
\end{tikzpicture}
\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{tikzpicture}[scale=0.9]
\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
can be retrieved in logarithmic time.
In the following code,
the priority queue
In the following code, the priority queue
\texttt{q} contains pairs of the form $(-d,x)$,
meaning that the current distance to node $x$ is $d$.
The array $\texttt{dist}$ contains the distance to
each node, and the array $\texttt{ready}$ indicates
The array $\texttt{distance}$ contains the distance to
each node, and the array $\texttt{processed}$ indicates
whether a node has been processed.
Initially the distance is $0$ to $x$ and $\infty$ to all other nodes.
\begin{lstlisting}
for (int i = 1; i <= n; i++) dist[i] = INF;
dist[x] = 0;
for (int i = 1; i <= n; i++) distance[i] = INF;
distance[x] = 0;
q.push({0,x});
while (!q.empty()) {
int a = q.top().second; q.pop();
if (ready[a]) continue;
ready[a] = true;
for (auto u : v[a]) {
if (processed[a]) continue;
processed[a] = true;
for (auto u : adj[a]) {
int b = u.first, w = u.second;
if (dist[a]+w < dist[b]) {
dist[b] = dist[a]+w;
q.push({-dist[b],b});
if (distance[a]+w < distance[b]) {
distance[b] = distance[a]+w;
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
elements, while we want to find minimum elements.
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
and use positive distances, but the implementation would be a bit longer.}.
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
that contains distances between the nodes.
First, the distances are calculated only using
direct edges between the nodes.
After this the algorithm reduces the distances
by using intermediate nodes in the paths.
First, distances are calculated only using
direct edges between the nodes,
and after this, the algorithm reduces distances
by using intermediate nodes in paths.
\subsubsection{Example}
@ -661,8 +662,7 @@ In this graph, the initial array is as follows:
The algorithm consists of consecutive rounds.
On each round, the algorithm selects a new node
that can act as an intermediate node in paths from now on,
and the algorithm reduces the distances in the array
using this node.
and distances are reduced using this node.
On the first round, node 1 is the new intermediate node.
There is a new path between nodes 2 and 4
@ -764,17 +764,17 @@ The advantage of the
FloydWarshall algorithm that it is
easy to implement.
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$.
First, the algorithm initializes \texttt{dist}
using the adjacency matrix \texttt{mat} of the graph:
First, the algorithm initializes \texttt{distance}
using the adjacency matrix \texttt{adj} of the graph:
\begin{lstlisting}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == j) dist[i][j] = 0;
else if (mat[i][j]) dist[i][j] = mat[i][j];
else dist[i][j] = INF;
if (i == j) distance[i][j] = 0;
else if (adj[i][j]) distance[i][j] = adj[i][j];
else distance[i][j] = INF;
}
}
\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 i = 1; i <= n; i++) {
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]);
}
}
}