zoukankan      html  css  js  c++  java
  • 求图的连通子图的个数并保存每个子图的节点python

    1.

    输入:

    第一行:第一个数代表有5个节点,第二个数代表下面还有多少行数据

    输出:

    连通子图的个数

    每个连通子图的节点(输出顺序为每个连通子图节点编号最小的先输出)

    输入: 

        # 测试数据一
        # 5 5
        # 1 2
        # 2 2
        # 3 1
        # 4 2
        # 5 4
    
        # 测试数据二
        # 5 5
        # 1 2
        # 2 3
        # 3 2
        # 4 5
        # 5 5

     输出:

    1
    1 2 3 4 5
    

     代码一: 

    def dfs(matrix,visited,i):
        for j in range(len(matrix)):
            if matrix[i][j]==1 and visited[j]==0:
                visited[j]=1
                id[j]=cnt
                dfs(matrix,visited,j)
    
    
    if __name__ == '__main__':
        n, m = list(map(int, input().split()))
        data = []
        for _ in range(m):
            data.append(list(map(int,input().split())))
            pass
        matrix=[[0]*n  for _ in range(n)]
        visited=[0]*n  # 记录每个节点是否被访问过
        for i in range(n):
            matrix[i-1][i-1]=1
        for i,j in data:
            matrix[i-1][j-1]=1
            matrix[j - 1][i - 1] = 1
        print(matrix)
        cnt=0
        result=[]  # 记录每个连通区域节点的二维列表,其实可以直接根据id列表的信息,每判断个节点属于哪个联通分区
        ready=set()  # 已经放进了result列表的节点会被加入到ready
        for i in range(len(matrix)):
            if visited[i]==0:
                dfs(matrix,visited,i)
                cnt+=1
            tmp = []
            for idx, ele in enumerate(visited):
                if ele == 1 and idx + 1 not in ready:  # 
                    tmp.append(idx + 1)  # 没有放进ready的节点会被加入到tmp,随后添加到result
                    ready.add(idx + 1)  #被添加到result的节点 记录到ready中
            if len(tmp)!=0: # 循环为执行len(matrix)次,但是连通分区数目小于等于最大节点数,所以需要判断,避免添加空列表到result
                result.append(tmp)
        print(cnt,result,id)
    
    

    用一个id列表,长度等于节点数目,简化代码。因为只通过id记录了每个节点对应的联通分区数目。

     
    
    
    def dfs(matrix,visited,i,cnt,id):
        for j in range(len(matrix)):
            if matrix[i][j]==1 and visited[j]==0:
                visited[j]=1
                id[j]=cnt
                dfs(matrix,visited,j,cnt,id)
    if __name__ == '__main__':
        n, m = list(map(int, input().split()))
        data = []
        for _ in range(m):
            data.append(list(map(int,input().split())))
            pass
        matrix=[[0]*n  for _ in range(n)]
        visited=[0]*n  # 记录每个节点是否被访问过
        id=[-1]*n # 记录每个节点对应的联通分区编号
        for i in range(n):
            matrix[i-1][i-1]=1
        for i,j in data:
            matrix[i-1][j-1]=1
            matrix[j - 1][i - 1] = 1
        print(matrix)
        cnt=0
        for i in range(len(matrix)):
            if visited[i]==0:
                dfs(matrix,visited,i,cnt,id)
                cnt+=1
        print(cnt,id)
    
    
    输出:
    [[1, 1, 0, 0, 0], [1, 1, 1, 0, 0], [0, 1, 1, 0, 0], [0, 0, 0, 1, 1], [0, 0, 0, 1, 1]]
    2 [0, 0, 0, 1, 1]
     
  • 相关阅读:
    Java StringBuilder、基本类型的包装类
    立个Flag不学好PHP誓不罢休
    LAMP搭建 转
    CentOS使用yum源中自带的rpm包安装LAMP环境
    CentOS RedHat YUM 源扩展补充(32位、64位均有)
    解决phpmyadmin上传文件大小限制的配置方法
    lanmp v2.5一键安装包发布(包括lamp,lnmp,lnamp安装)
    图像处理 jpg png gif svg
    NAT模式/路由模式/全路由模式 (转)
    网页制作中绝对路径和相对路径的区别
  • 原文地址:https://www.cnblogs.com/sunupo/p/13510172.html
Copyright © 2011-2022 走看看