Skip to content

Commit 698d711

Browse files
authored
Merge pull request #44 from nalinbhardwaj/master
Translated article on searching for bridges
2 parents dabda9e + 0bf3bed commit 698d711

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

src/graph/bridge-searching.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<!--?title Searching for bridges in a graph in O(N+M) -->
2+
3+
# Searching for bridges
4+
5+
Suppose that we are given an undirected graph. A bridge is defined as an edge, whose removal makes the graph disconnected(or more precisely, increases the number of connected components). You want to find all the bridges in a given graph.
6+
7+
Informally, the problem is formulated as follows: Given a map of cities with roads between them, find all "important" roads, i.e. roads whose removal leads to disappearance of the path between some pair of cities.
8+
9+
Below, we describe the algorithm based of [depth first search](http://e-maxx.ru/algo/dfs), having running time $O(n+m)$, where $n$ is the number of vertices, and $m$ is the number of edges in the graph.
10+
11+
Note that the website also describes an [online algorithm for finding bridges](http://e-maxx.ru/algo/bridge_searching_online) - in contrast to the offline algorithm described here, the online algorithm is able to maintain all bridges in a graph that is changing(new edges are being added).
12+
13+
## Algorithm
14+
15+
Run [DFS](http://e-maxx.ru/algo/dfs) from an arbitrary vertex of the graph; lets denote it through $root$. We note the following fact(which is easy to prove):
16+
17+
- Let's say we are in the DFS, and looking through the edges from vertex $v$. Then for some edge $(v, to)$, it is a bridge if the vertices $to$ and it's descendants in the DFS tree have no back-edges to vertex $v$ or any of it's ancestors. Otherwise, the edge must not be a bridge. (In fact, we check the condition that there is no other way from $v$ to $to$ except for edge $(v, to)$ traversing the DFS tree.)
18+
19+
Now we have to learn how to effectively verify this fact for each vertex. For doing this, we use "time of entry into node", computed by the depth first search algorithm.
20+
21+
So, let $tin[v]$ denote the the depth first search time of node $v$. Now, we introduce the array $fup[v]$, which is the minimum of $tin[v]$, the DFS time of all nodes $p$ that are connected to node $v$ via back-edge $(v, p)$ and all the values of $fup[to]$ for each vertex to which is a direct child of $v$ in the DFS tree.
22+
23+
<pre><img src="http://e-maxx.ru/tex2png/cache/ec0a7c417df6f6cbc5ef762cd909127f.png" alt=" fup[v] = \min \cases{
24+
tin[v], &amp; \cr
25+
tin[p], &amp; {[...]"></pre>
26+
27+
Now, there is a back edge from node $v$ or it's descendants if there is a son $to$ of node $v$ such that $fup[to] \leq tin[v]$.(If $fup[to] = tin[v]$, it means back edge comes directly to $v$, otherwise it comes to some ancestor).
28+
29+
Thus, if the current edge $(v, to)$ in the DFS tree satisfies $fup[to] > tin[v]$, then it must be a bridge; otherwise it isn't one.
30+
31+
##Implementation
32+
33+
Regarding the implementation, here we need to distinguish 3 cases: when we are on an edge to a child in DFS tree, when we try to go on a back edge to some ancestor and when we are going in the reverse direction to our parent. Therefore, these are the cases accordingly:
34+
35+
- $used[to] = false$ - DFS tree edges criteria;
36+
- $used[to] = true$ && $to \neq parent$ - back edge to some ancestor criteria;
37+
- $to = parent$ - Criteria for edge to be edge to parent in DFS tree.
38+
39+
Thus, to implement, we need a depth first search function with all the information for a current node.
40+
41+
C++ implementation <span class="toggle-code">Show/Hide</span>
42+
43+
<pre><code>const int MAXN = ...;
44+
vector&lt;int&gt; g[MAXN];
45+
bool used[MAXN];
46+
int timer, tin[MAXN], fup[MAXN];
47+
48+
void dfs (int v, int p = -1) {
49+
used[v] = true;
50+
tin[v] = fup[v] = timer++;
51+
for (size_t i = 0; i < g[v].size(); ++i) {
52+
int to = g[v][i];
53+
if (to == p) continue;
54+
if (used[to])
55+
fup[v] = min (fup[v], tin[to]);
56+
else {
57+
dfs (to, v);
58+
fup[v] = min (fup[v], fup[to]);
59+
if (fup[to] > tin[v])
60+
IS_BRIDGE(v,to);
61+
}
62+
}
63+
}
64+
65+
void find_bridges() {
66+
timer = 0;
67+
for (int i = 0; i < n; ++i)
68+
used[i] = false;
69+
for (int i = 0; i < n; ++i)
70+
if (!used[i])
71+
dfs (i);
72+
} </code></pre>
73+
74+
</span>
75+
76+
Here, the main function calls function $find$_$bridges$ which produces necessary initialization and starts depth first search in all components of a graph.
77+
78+
Function $IS$_$BRIDGE(a, b)$ - is a function that will produce output to the fact that edge $(a, b)$ is a bridge.
79+
80+
Constant $MAXN$ at beginning of code is initialised to maximum number of nodes in the graph.
81+
82+
It should be noted that this does not work correctly if multiple edges are present in the graph, as it actually ignores their presence. Of course, multiple edges must not be a part of the answer, so checks must be made in the function $IS$_$BRIDGE$. Another way to work with multiple edges more accurately is to transfer the number of edges by which we entered the current node(we all need to store this additionally).
83+
84+
## Tasks in online judges
85+
86+
Some tasks in which we aim to find bridges:
87+
88+
- [UVA #796 "Critical Links" [difficulty: low]](http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=737)
89+
- [UVA #610 "Street Directions" [difficulty: medium]](http://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=551)
90+
- [Case of the Computer Network (Codeforces Round #310 Div. 1 E) [difficulty: hard]](http://codeforces.com/problemset/problem/555/E)
91+
92+
####Note: Translated by [NibNalin](http://codeforces.com/profile/NibNalin)

src/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ especially popular in field of competitive programming.*
3939
- [Breadth First Search](./graph/breadth-first-search.html)
4040
- [Kirchhoff theorem](./graph/kirchhoff-theorem.html)
4141
- [Topological sorting](./graph/topological-sort.html)
42-
42+
- [Searching for bridges in O(N+M)](./graph/bridge-searching.html)
4343
---
4444

4545
[Information for contributors](./contrib.html) and [Test-Your-Page form](./test.php)

0 commit comments

Comments
 (0)