diff --git a/graphs/finding_bridges.py b/graphs/finding_bridges.py index 6555dd7bc29e997eaa981a883846db5ee2701883..a877a97489bec7501c25a2c46b3d75476271d8a2 100644 --- a/graphs/finding_bridges.py +++ b/graphs/finding_bridges.py @@ -1,5 +1,77 @@ -# Finding Bridges in Undirected Graph -def computeBridges(graph): +""" +An edge is a bridge if, after removing it count of connected components in graph will +be increased by one. Bridges represent vulnerabilities in a connected network and are +useful for designing reliable networks. For example, in a wired computer network, an +articulation point indicates the critical computers and a bridge indicates the critical +wires or connections. + +For more details, refer this article: +https://www.geeksforgeeks.org/bridge-in-a-graph/ +""" + + +def __get_demo_graph(index): + return [ + { + 0: [1, 2], + 1: [0, 2], + 2: [0, 1, 3, 5], + 3: [2, 4], + 4: [3], + 5: [2, 6, 8], + 6: [5, 7], + 7: [6, 8], + 8: [5, 7], + }, + { + 0: [6], + 1: [9], + 2: [4, 5], + 3: [4], + 4: [2, 3], + 5: [2], + 6: [0, 7], + 7: [6], + 8: [], + 9: [1], + }, + { + 0: [4], + 1: [6], + 2: [], + 3: [5, 6, 7], + 4: [0, 6], + 5: [3, 8, 9], + 6: [1, 3, 4, 7], + 7: [3, 6, 8, 9], + 8: [5, 7], + 9: [5, 7], + }, + { + 0: [1, 3], + 1: [0, 2, 4], + 2: [1, 3, 4], + 3: [0, 2, 4], + 4: [1, 2, 3], + }, + ][index] + + +def compute_bridges(graph: dict[int, list[int]]) -> list[tuple[int, int]]: + """ + Return the list of undirected graph bridges [(a1, b1), ..., (ak, bk)]; ai <= bi + >>> compute_bridges(__get_demo_graph(0)) + [(3, 4), (2, 3), (2, 5)] + >>> compute_bridges(__get_demo_graph(1)) + [(6, 7), (0, 6), (1, 9), (3, 4), (2, 4), (2, 5)] + >>> compute_bridges(__get_demo_graph(2)) + [(1, 6), (4, 6), (0, 4)] + >>> compute_bridges(__get_demo_graph(3)) + [] + >>> compute_bridges({}) + [] + """ + id = 0 n = len(graph) # No of vertices in graph low = [0] * n @@ -15,28 +87,14 @@ def computeBridges(graph): elif not visited[to]: dfs(to, at, bridges, id) low[at] = min(low[at], low[to]) - if at < low[to]: - bridges.append([at, to]) + if id <= low[to]: + bridges.append((at, to) if at < to else (to, at)) else: # This edge is a back edge and cannot be a bridge - low[at] = min(low[at], to) + low[at] = min(low[at], low[to]) bridges = [] for i in range(n): if not visited[i]: dfs(i, -1, bridges, id) - print(bridges) - - -graph = { - 0: [1, 2], - 1: [0, 2], - 2: [0, 1, 3, 5], - 3: [2, 4], - 4: [3], - 5: [2, 6, 8], - 6: [5, 7], - 7: [6, 8], - 8: [5, 7], -} -computeBridges(graph) + return bridges