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]