diff --git a/src/graph/01_bfs.md b/src/graph/01_bfs.md index 5d7aee6f4..d6f38e531 100644 --- a/src/graph/01_bfs.md +++ b/src/graph/01_bfs.md @@ -15,29 +15,44 @@ In this article we demonstrate how we can use BFS to solve the SSSP (single-sour ## Algorithm We can develop the algorithm by closely studying Dijkstra's algorithm and thinking about the consequences that our special graph implies. -The general form of Dijkstra's algorithm is (here a `set` is used for the priority queue): - -```cpp -d.assign(n, INF); -d[s] = 0; -set> q; -q.insert({0, s}); -while (!q.empty()) { - int v = q.begin()->second; - q.erase(q.begin()); - - for (auto edge : adj[v]) { - int u = edge.first; - int w = edge.second; - - if (d[v] + w < d[u]) { - q.erase({d[u], u}); - d[u] = d[v] + w; - q.insert({d[u], u}); +The general form of Dijkstra's algorithm is: + +=== "C++" + ```cpp + int n = adj.size(); + d.assign(n, INF); + d[s] = 0; + priority_queue,vector>, greater> > q; + q.push({0,s}); + while (!q.empty()) { + auto [dv, v] = q.top(); + q.pop(); + if (dv == d[v]) { + for (auto [u, w] : adj[v]) { + if (d[v] + w < d[u]) { + d[u] = d[v] + w; + q.push({d[u], u}); + } + } } } -} -``` + ``` +=== "Python" + ```py + from heapq import heappop, heappush + + + d = [float("inf")] * n + d[s] = 0 + q = [(0, s)] + while q: + dv, v = heappop(q) + if dv == d[v]: + for u, w in adj[v]: + if d[v] + w < d[u]: + d[u] = d[v] + w + heappush(q, (d[u], u)) + ``` We can notice that the difference between the distances between the source `s` and two other vertices in the queue differs by at most one. Especially, we know that $d[v] \le d[u] \le d[v] + 1$ for each $u \in Q$. @@ -53,27 +68,40 @@ This structure is so simple, that we don't need an actual priority queue, i.e. u We can simply use a normal queue, and append new vertices at the beginning if the corresponding edge has weight $0$, i.e. if $d[u] = d[v]$, or at the end if the edge has weight $1$, i.e. if $d[u] = d[v] + 1$. This way the queue still remains sorted at all time. -```cpp -vector d(n, INF); -d[s] = 0; -deque q; -q.push_front(s); -while (!q.empty()) { - int v = q.front(); - q.pop_front(); - for (auto edge : adj[v]) { - int u = edge.first; - int w = edge.second; - if (d[v] + w < d[u]) { - d[u] = d[v] + w; - if (w == 1) - q.push_back(u); - else - q.push_front(u); +=== "C++" + ```cpp + vector d(n, INF); + d[s] = 0; + deque q = {s}; + while (!empty(q)) { + int v = q.front(); + q.pop_front(); + for (auto [u, w] : adj[v]) { + if (d[v] + w < d[u]) { + d[u] = d[v] + w; + if (w == 1) + q.push_back(u); + else + q.push_front(u); + } } } -} -``` + ``` +=== "Python" + ```py + d = [float("inf")] * n + d[s] = 0 + q = deque([s]) + while q: + v = q.popleft() + for u, w in adj[v]: + if d[v] + w < d[u]: + d[u] = d[v] + w + if w == 1: + q.append(u) + else: + q.appendleft(u) + ``` ## Dial's algorithm