Small fixes
This commit is contained in:
parent
1ee57c911b
commit
7eb756088f
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
Floyd–Warshall algorithm that it is
|
Floyd–Warshall 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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue