【算法】图 (5) 强连通图

如何判断一个图是强连通图?

强连通图(strongly connected):在一个图中,任意两点x,y,都可以互相到达(可以借助其他点作为中转);

1 简单方法

对每个结点进行DFS或者BFS搜索,如果每次搜索的结果,使得每个点的state都标记为“Processed”,则表示该图为强连通图,时间复杂度为O(n(n+m))),其中O(n+m)是DFS的时间复杂度;

2 通过hub来判断强连通图

先验知识:

2.1 图的转置

图中所有的点不变,但是所有的边的方向都反向

输入样例:

graph_string = """\
D 3 W
0 1 7
1 0 -2
0 2 0
"""

转换为邻接表:

代码:

def transpose(graph_adj_list):
    ans = [[] for i in range(len(graph_adj_list))]
    for i, edges in enumerate(graph_adj_list):
        for edge in edges:# i mean index, edge mean every edge in edges
            start = i
            end = edge[0]
            tup = (start, edge[1])
            ans[end].append(tup)
    return ans            

graph_string = """\
D 3 W
0 1 7
1 0 -2
0 2 0
"""

graph_adj_list = adjacency_list(graph_string)
print(graph_adj_list)
graph_transposed_adj_list = transpose(graph_adj_list)
for i in range(len(graph_transposed_adj_list)):
    print(i, sorted(graph_transposed_adj_list[i]))

2.2 Hub (中心)

一个点h为hub的条件:(a) h可以到达图中的所有点,(b) 图中的所有点可以到达h。

  • 如果一个图中存在一个hub h,那么该图就为强连通图;?
  • 因为图中的任意两个点都可以通过hub h进行中转,所以该图中任意两个点都互联。
  • 另外的,如果该图中所有的点都可以通过该hub h进行中转而相连,也就表示该图中的所有点都为hub。

2.3 判断强连通图

根据上述定义,判断强连通图的步骤为:

  1. 在图G上任意选择一点h,进行DFS或者BFS搜索;
  2. 如果图G上存在一个点为“Undiscovered”,则返回False;
  3. 构建图G的转置图G'
  4. 在G'上选择相同的点h,进行DFS或者BFS搜索;
  5. 如果图G'上存在一个点为“Undiscovered”,则返回False;
  6. 否则就返回True;

将图转置,即将所有的边反向,在1中进行搜索,保证了条件(a);转之后,在4中再次进行搜索,保证了条件(b);最后如果两次搜索都没有点‘Undiscovered’,则表示点h为hub,则由对hub的结论可知,该图为强连通图;

def is_strongly_connected(adj_list):
    state1 = dfs_tree(adj_list, 0)  #step 1  
    for state in state1:     
        if state != 'P':
            return False            #step 2
    adj_list1 = transpose(adj_list) #step 3    
    state2 = dfs_tree(adj_list1, 0) #step 4
    for state in state2:     
        if state != 'P':
            return False            #step 5
    return True                     #step 6

该算法的时间复杂度为2*O(n+m)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值