关节点和重连通分量,trajan算法实现(python)

这篇博客介绍了如何利用深度优先搜索算法来寻找图中的关节点,以及如何判断图是否为重连通图。通过构建深度优先生成树,可以发现关节点的两个特性:根节点拥有两棵或更多子树,或者非叶子节点的某子树根与其他节点无回边指向其祖先。给定一个无向图的邻接矩阵,代码实现了找到所有关节点并输出的功能。
摘要由CSDN通过智能技术生成

问题:关节点和重连通分量

题目描述
假若在删去顶点v以及和v相关联的各边之后,将图的一个连通分量分割成两个或两个以上的连接分量,则称顶点v为该图的一个关节点。一个没有关节点的连通图称为重连通图。在重连通图上,任意一对顶点之间至少存在两条路径,则在删去某个顶点以及依附于该顶点的各边时也不会破坏图的连通性。
利用深度优先搜索可以求出图的关节点,并由此可以判断图是否是重连通的。
通过修改深度优先搜索遍历的算法便可以得到求关节点的算法,其算法描述如下:
在本题中,读入一个无向图的邻接矩阵(即数组表示),建立无向图并按照以上描述中的算法求出所有的关节点,并输出这些关节点。

输入 :
输入的第一行包含一个正整数n,表示图中共有n个顶点。其中n不超过50。
以后的n行中每行有n个用空格隔开的整数0或1,对于第i行的第j个整数,如果为1,则表示第i个顶点和第j个顶点有直接连接,0表示没有直接连接。当i和j相等的时候,保证对应的整数为0。
输入保证邻接矩阵为对称矩阵,即输入的图一定是无向图,且保证图中只有一个连通分量。
输出:
第一行有一个整数x,即图中关节点的个数。
第二行输出x个整数,表示所有关节点的顶点编号,请按照编号从小到大的顺序输出。每个整数后输出一个空格,并请注意行尾输出换行。
样例输入
4
01 1 1
1 0 0 0
1 0 0 0
1 0 0 0
样例输出
1
0
提示
在本题中,需要掌握图的深度优先遍历的方法,并需要掌握通过深度优先搜索求得图中关节点的算法。通过生成深度优先生成树可以得出两类关节点的特性:

  • 若生成树的根有两棵或两棵以上的子树,则此根顶点必为关节点。

  • 若生成树中某个非叶子顶点v,其某棵子树的根和子树中的其他结点均没有指向v的祖先的回边,则说明v是关节点。

注意以上两点特性,就可以成功的通过深度优先搜索遍历的算法得出图中的关节点了。

代码展示:

n = int(input())
visited=[0]*n#访问列表,用于判断节点访问状态
low=[1000000]*n#初始化权值列表
count=0
end_ans=[]#结果列表
def DFS(G,v0):
    global count,visited,low,n,end_ans
    count+=1
    visited[v0]=min=count
    for i in range(0,n):
        if G[v0][i]!=0:#读入邻接节点
            if visited[i]==0:
                DFS(G,i)
                if low[i]<min:
                    min=low[i]
                if low[i]>=visited[v0]:
                    end_ans.append(v0)
            else:
                if visited[i]<min:
                    min=visited[i]
    low[v0]=min

def FindArticul(G):
        global  visited,count,n,end_ans
        visited[0]=1
        count=1
        for i in range(1,n):
            if G[0][i]!=0:
                DFS(G,i)
                if count<n:
                    end_ans.append(0)
                    while i<n:
                        if G[0][i]!=0 and visited[i]==0:
                            DFS(G,i)
                        i+=1
                    return
if __name__=='__main__':
    G=[]#无向连通图-邻接矩阵形式
    for i in range(0, n):
        res = input()
        ans = res.split(' ')
        G.append([int(i) for i in ans])
    FindArticul(G)
    print(len(end_ans))
    end_ans.sort()
    for i in end_ans:
        print(i,end=' ')
    print()
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

看不见的罗辑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值