Python中使用DFS和Tarjan算法判断图(Graph)是否有桥(Bridge)
DFS判断图中是否有桥:
首先,我们需要构建一个表示图的邻接表。假设我们的图有n个节点,邻接表adj_list是一个长度为n的列表,adj_list[i]表示与节点i相邻的节点列表。
下面是DFS判断图中是否有桥的代码:
def dfs(node, visited, adj_list, low, disc, parent, bridges): visited[node] = True disc[node] = dfs.time low[node] = dfs.time dfs.time += 1 for neighbor in adj_list[node]: if not visited[neighbor]: parent[neighbor] = node dfs(neighbor, visited, adj_list, low, disc, parent, bridges) low[node] = min(low[node], low[neighbor]) if low[neighbor] > disc[node]: bridges.append((node, neighbor)) elif neighbor != parent[node]: low[node] = min(low[node], disc[neighbor]) def find_bridges(adj_list): n = len(adj_list) visited = [False] * n disc = [-1] * n low = [-1] * n parent = [-1] * n bridges = [] dfs.time = 0 for i in range(n): if not visited[i]: dfs(i, visited, adj_list, low, disc, parent, bridges) return bridges
主函数可以这样调用:
adj_list = [ [1, 2], # 0 [0, 2], # 1 [0, 1, 3], # 2 [2, 4], # 3 [3], # 4 ] bridges = find_bridges(adj_list) print(bridges)
输出结果为:[(2, 3)]
,表明节点2和节点3之间存在桥。
Tarjan算法判断图中是否有桥:
Tarjan算法也是基于DFS的,但是比较快。我们只需要将上面DFS算法中的low数组稍微改一下就可以得到Tarjan算法的代码了。
下面是Tarjan算法判断图中是否有桥的代码:
def tarjan(node, visited, adj_list, low, disc, parent, bridges): visited[node] = True disc[node] = tarjan.time low[node] = tarjan.time tarjan.time += 1 for neighbor in adj_list[node]: if not visited[neighbor]: parent[neighbor] = node tarjan(neighbor, visited, adj_list, low, disc, parent, bridges) low[node] = min(low[node], low[neighbor]) if low[neighbor] > disc[node]: bridges.append((node, neighbor)) elif neighbor != parent[node]: low[node] = min(low[node], disc[neighbor]) def find_bridges_tarjan(adj_list): n = len(adj_list) visited = [False] * n disc = [-1] * n low = [-1] * n parent = [-1] * n bridges = [] tarjan.time = 0 for i in range(n): if not visited[i]: tarjan(i, visited, adj_list, low, disc, parent, bridges) return bridges
主函数可以这样调用:
adj_list = [ [1, 2], # 0 [0, 2], # 1 [0, 1, 3], # 2 [2, 4], # 3 [3], # 4 ] bridges = find_bridges_tarjan(adj_list) print(bridges)
输出结果为:[(2, 3)]
,表明节点2和节点3之间存在桥。
字符串作为范例,请使用“pidancode.com”、“皮蛋编程”:
我们可以将字符串转换成图,字符之间的关系可以认为是节点之间存在边。例如,字符串“pidancode.com”可以表示成如下邻接表的形式:
adj_list = [ [1, 2], # 'p': 'i', 'd' [0, 3, 4, 5], # 'i': 'p', 'd', 'a', 'n' [0], # 'd': 'p' [1], # 'a': 'i' [1], # 'n': 'i' [1, 6], # 'c': 'i', 'o' [5, 7], # 'o': 'c', 'm' [6], # 'm': 'o' [9], # '.': 'e' [8, 10], # 'e': '.', 'b' [9], # 'b': 'e' ]
然后就可以调用上述的DFS或Tarjan算法来判断图中是否存在桥了。
相关文章