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]