Skip to content

Commit e4f2bd2

Browse files
committed
reformulate a few expressions, modernize code, tex
1 parent 31e6ffd commit e4f2bd2

1 file changed

Lines changed: 51 additions & 40 deletions

File tree

src/graph/breadth-first-search.md

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
# Breadth-first search
44
Breadth first search is one of the basic and essential searching algorithms on graphs.
55

6-
As a result of how the algorithm works, the path found by breadth first search to any node is the shortest path to that node i.e
7-
the path that contains the smallest number of edges in unweighted graphs.
6+
As a result of how the algorithm works, the path found by breadth first search to any node is the shortest path to that node, i.e the path that contains the smallest number of edges in unweighted graphs.
87

9-
The algorithm works in $O (n + m)$ time, where $n$ is number of vertices and $m$ is the number of edges.
8+
The algorithm works in $O(n + m)$ time, where $n$ is number of vertices and $m$ is the number of edges.
109

1110
## Description of the algorithm
1211

@@ -17,82 +16,94 @@ The algorithm can be understood as a fire spreading on the graph: at the zeroth
1716
fire" is expanded in width by one unit (hence the name of the algorithm).
1817

1918
More precisely, the algorithm can be stated as follows: Create a queue $q$ which will contain the vertices to be processed and a
20-
boolean array $used[]$ which indicates for each vertex, if it has been lit (or visited) or not.
19+
Boolean array $used[]$ which indicates for each vertex, if it has been lit (or visited) or not.
2120

22-
Initially, push the source $s$ to the queue and set $used[s] = true$, while for all other vertices, $used[] = false$. Then, loop until the queue is empty and in each iteration, pop a vertex from the front of the queue. Iterate through all the edges going out
21+
Initially, push the source $s$ to the queue and set $used[s] = true$, and for all other vertices $v$ set $used[v] = false$.
22+
Then, loop until the queue is empty and in each iteration, pop a vertex from the front of the queue. Iterate through all the edges going out
2323
of this vertex and if some of these edges go to vertices that are not already lit, set them on fire and place them in the queue.
2424

25-
As a result, when the queue is empty, the "ring of fire" contains all vertices reachable from the source $s$, with each vertex
26-
begin reached in the shortest possible way. You can also calculate the lengths of the shortest paths (which just requires maintaining an array of path lengths $d[]$) as well as save information to restore all of these shortest paths (for this, it is
27-
necessary to maintain an array of "parents" $p[]$, which stores for each vertex, the vertex number from which we reached here).
25+
As a result, when the queue is empty, the "ring of fire" contains all vertices reachable from the source $s$, with each vertex reached in the shortest possible way.
26+
You can also calculate the lengths of the shortest paths (which just requires maintaining an array of path lengths $d[]$) as well as save information to restore all of these shortest paths (for this, it is necessary to maintain an array of "parents" $p[]$, which stores for each vertex the vertex from which we reached it).
2827

2928
## Implementation
3029

3130
We write code for the described algorithm in C++.
3231

3332
```cpp
34-
// Input Data:
35-
vector < vector<int> > g; // adjacency list representation of graph
36-
int n; // number of nodes in the graph
37-
int s; // the source vertex
38-
// take input ...
33+
vector<vector<int>> adj; // adjacency list representation
34+
int n; // number of nodes
35+
int s; // source vertex
3936

40-
// Breadth first Search:
4137
queue<int> q;
42-
q.push (s);
43-
vector<bool> used (n);
44-
vector<int> d (n), p (n);
38+
vector<bool> used(n);
39+
vector<int> d(n), p(n);
40+
41+
q.push(s);
4542
used[s] = true;
4643
p[s] = -1;
4744
while (!q.empty()) {
4845
int v = q.front();
4946
q.pop();
50-
for (size_t i = 0; i < g[v].size(); ++i) {
51-
int to = g[v][i];
52-
if (!used[to]) {
53-
used[to] = true;
54-
q.push (to);
55-
d[to] = d[v] + 1;
56-
p[to] = v;
47+
for (int u : adj[v]) {
48+
if (!used[u]) {
49+
used[u] = true;
50+
q.push(u);
51+
d[u] = d[v] + 1;
52+
p[u] = v;
5753
}
5854
}
5955
}
6056
```
6157
62-
If we have to restore and display the shortest path from the source to some vertex $to$, it can be done in the following
63-
manner:
58+
If we have to restore and display the shortest path from the source to some vertex $u$, it can be done in the following manner:
6459
6560
```cpp
66-
if (!used[to])
61+
if (!used[u]) {
6762
cout << "No path!";
68-
else {
63+
} else {
6964
vector<int> path;
70-
for (int v=to; v!=-1; v=p[v])
71-
path.push_back (v);
72-
reverse (path.begin(), path.end());
65+
for (int v = u; v != -1; v = p[v])
66+
path.push_back(v);
67+
reverse(path.begin(), path.end());
7368
cout << "Path: ";
74-
for (size_t i=0; i<path.size(); ++i)
75-
cout << path[i] + 1 << " ";
69+
for (int v : path)
70+
cout << v << " ";
7671
}
7772
```
7873

7974
## Applications of BFS
8075

8176
* Find the shortest path from a source to other vertices in an unweighted graph.
8277

83-
* Find all connected components in a graph in O (n + m) time.: To do this, we just run BFS from each vertex, except for vertices which have already been visited from previous runs. Thus, we perform normal BFS from each of the vertices, but do not reset the array $used []$ each and every time, due to which every time we run a BFS, we get a new connected component, and the total running time will still be $O (n + m)$ (such multiple BFS on the graph without zeroing array $used []$ is called a series of breadth first searches).
78+
* Find all connected components in an undirected graph in $O(n + m)$ time:
79+
To do this, we just run BFS starting from each vertex, except for vertices which have already been visited from previous runs.
80+
Thus, we perform normal BFS from each of the vertices, but do not reset the array $used[]$ each and every time we get a new connected component, and the total running time will still be $O(n + m)$ (performing multiple BFS on the graph without zeroing the array $used []$ is called a series of breadth first searches).
8481

85-
* Finding a solution to a problem or a game with the least number of moves , if each state of the game can be represented by a vertex of the graph, and the transitions from one state to the other are the edges of the graph.
82+
* Finding a solution to a problem or a game with the least number of moves, if each state of the game can be represented by a vertex of the graph, and the transitions from one state to the other are the edges of the graph.
8683

87-
* Finding the shortest path in a graph with weights 0 or 1: This requires just a little modification to normal breadth-first search: if the current edge of zero weight, and distance to the vertex is shorter than the current found distance, then add this vertex not to the back, but to the front of the queue.
84+
* Finding the shortest path in a graph with weights 0 or 1:
85+
This requires just a little modification to normal breadth-first search: if the current edge of zero weight, and distance to the vertex is shorter than the current found distance, then add this vertex not to the back, but to the front of the queue.
8886

89-
* Finding the shortest cycle in a directed unweighted graph: start a breadth-first search from each vertex; as soon as we try to go from the current vertex from the queue to an already visited vertex, then it means that we have found the shortest cycle, and should stop the BFS; from all such cycles (one from each BFS), choose the shortest.
87+
* Finding the shortest cycle in a directed unweighted graph: start a breadth-first search from each vertex; as soon as we try to go from the current vertex to an already visited vertex, then it means that we have found the shortest cycle containing the source vertex, and should stop the BFS; from all such cycles (one from each BFS) choose the shortest.
9088

91-
* Find all the edges that lie on any shortest path between a given pair of vertices (a, b). To do this, run two breadth first searches: one from a and one from b. Let $d_a []$ be the array containing shortest distances obtained from the first BFS (from a) and $d_b []$ be the array containing shortest distances obtained from the second BFS from b. Now, for every edge (u, v), it is easy to check whether that edge lies on any shortest path between a and b: the criterion is the condition $d_a [u] + 1 + d_b [v] = d_a [b]$.
89+
* Find all the edges that lie on any shortest path between a given pair of vertices $(a, b)$.
90+
To do this, run two breadth first searches:
91+
one from $a$ and one from $b$.
92+
Let $d_a []$ be the array containing shortest distances obtained from the first BFS (from $a$) and $d_b []$ be the array containing shortest distances obtained from the second BFS from $b$.
93+
Now for every edge $(u, v)$ it is easy to check whether that edge lies on any shortest path between $a$ and $b$:
94+
the criterion is the condition $d_a [u] + 1 + d_b [v] = d_a [b]$.
9295

93-
* Find all the vertices on any shortest path between a given pair of vertices (a, b). To do this, run two breadth first searches: one from a and one from b. Let $d_a []$ be the array containing shortest distances obtained from the first BFS (from a) and $d_b []$ be the array containing shortest distances obtained from the second BFS from b. Now, for each vertex, it is easy to check whether it lies on any shortest path between a and b: the criterion is the condition $d_a [v] + d_b [v] = d_a [b]$.
96+
* Find all the vertices on any shortest path between a given pair of vertices $(a, b)$.
97+
To accomplish that, run two breadth first searches:
98+
one from $a$ and one from $b$.
99+
Let $d_a []$ be the array containing shortest distances obtained from the first BFS (from $a$) and $d_b []$ be the array containing shortest distances obtained from the second BFS (from $b$).
100+
Now for each vertex it is easy to check whether it lies on any shortest path between $a$ and $b$:
101+
the criterion is the condition $d_a [v] + d_b [v] = d_a [b]$.
94102

95-
* Find the shortest path of even length from start vertex to end vertex in an unweighted graph: For this, we must construct an auxiliary graph, whose vertices are the state (v, c), where v- the number of current node, c = 0 or 1- the current parity. Any edge (a, b) of the original graph in this new column will turn into two edges ((u, 0), (v, 1))and ((u, 1), (v, 0)). After that, on this graph, we need to run a BFS to find the shortest path from the starting vertex to the end, with parity, equal to 0.
103+
* Find the shortest path of even length from a source vertex $s$ to a target vertex $t$ in an unweighted graph:
104+
For this, we must construct an auxiliary graph, whose vertices are the state $(v, c)$, where $v$ - the current node, $c = 0$ or $c = 1$ - the current parity.
105+
Any edge $(a, b)$ of the original graph in this new column will turn into two edges $((u, 0), (v, 1))$ and $((u, 1), (v, 0))$.
106+
After that we run a BFS to find the shortest path from the starting vertex $(s, 0)$ to the end vertex $(t, 0)$.
96107

97108
## Practice Problems
98109

0 commit comments

Comments
 (0)