BFS를 그래프 문제를 풀면서 이해해보자!
BFS는 너비우선탐색으로, 가까운 노드들부터 탐색하면서 길을 헤쳐나간다.
1이 시작노드면, 2,3 탐색하고 / 다음 2와 가까운 4,5 탐색 <- 이런식으로 진행된다.
** 주의할점 - 방문했던 노드를 또 다시 방문하는 건 비효율적이고, 무한루프가 될 가능성이 있으므로 방문했던 노드는 체크표시를 하면서 진행한다.
-> 노드 방문 순서 1,2,3,4,5,7,8,6
인접행렬 : 그래프에서 어느 꼭짓점들이 변으로 연결되었는지 나타내는 정사각 행렬
-> 간단히 말해서, 모든 배열이 0으로 초기화 되어 있고 갈 수 있는 정점에 한해서는 1로 표시되어 있는 행렬이다.
ex) 2가 갈 수 있는 정점은 3뿐이니, 3에만 1이 적혀있다. / 1이 갈 수 있는 정점은 2,3,4여서 2,3,4에 1이 적힘
-> 즉, 밑의 그림처럼 나타낼 수 있다.
-> 각 정점에 어떤 방법을 써서든 도달할 수 있으면 1, 도달할 수 없으면 0을 출력한다.
ex) 0에서 0으로 가는 방법 : 있음 (1) / 0에서 2로 가는 방법 : 있음 (1)
입력받기
N = int(input())
arr=[list(map(int,input().split())) for _ in range(N)]
bfs를 돌아서, 만약 길을 다 돌았는데 길이 없으면 print(0), 중간에 길을 찾으면 print(1)하고 return하는 함수를 호출
for i in range(N):
for j in range(N):
bfs(i, j)
print()
위에서 말한 함수 정의
함수는 BFS를 사용하므로, 아까 위에서 배웠던 bfs를 가져온다!
# 1. Queue 만들어줌
deq = deque()
# 2. 방문했는지 체크여부 만들어줌
visited = [0 for i in range(N)]
# 3. 큐에 첫 번째 값 넣음
deq.append(start)
# 4. while 문을 돌린다(큐가 없어질 때까지 계속 실행)
while len(deq)!=0:
# 5. 큐에서 노드 꺼내기
current = deq.popleft()
# 6. 인접한 노드 찾음
for i in range(N):
# 7. 간선이 연결되어 있고(인접한 노드이고), 방문을 하지 않은 곳이라면?
if(arr[current][i]==1 and visited[i]==0):
# 8. 방문 됐다고 표시
visited[i] = 1
# 9. 그 노드를 큐에 넣음
deq.append(i)
-> 이게 수도코드를 변환한 코드이다.
여기서 우리는 길이 있다면 print(1)을 찍고, 없다면 print(0)을 찍어야 한다.
-> 위의 코드를 조금만 변형하면 할 수 있다
-> 우리는 bfs인자로 start, end를 줬었다.
=> 만약 0에서 2로 갈 수 있는지 없는지를 탐색하기 원한다면 bfs(0,2)로 함수가 들어오는 것이다.
그럼 인접한 노드의 반복문을 돌릴 때 그 중에서 2가 있다면? print(1)을 해주면 된다
# 7번 코드를 가져온다.
if(arr[current][i]==1 and visited[i]==0): # 인접한 노드 중에서 방문을 하지 않은 곳이라면?
if(i==end): # 인접한 노드와 2가 일치한다면, print(1)을 해주고 return 한다.
print(1, end=" ")
return
-> 그리고, while문이 다 끝난 후에도 return이 안 됐다면 print(0)을 찍어주면 끝
0에서 2로 갈 수 있는 길이 있는지 없는지 궁금하다.
0에서 2로 갈 수 있는 길을 알고싶으면 우리가 만든 bfs 함수에 인자로 (0,2)를 넣어주게 될 것이다.
=> bfs(0,2) 이런식!
그럼, 간선을 따라 방문하는 반복문 코드에서 2가 나타난다면! print(1)을 해주면 된다
-> 간선을 따라 방문하는 반복문 코드는 어떤 식으로 이루어져 있지?
from collections import deque
N = int(input())
arr=[list(map(int,input().split())) for _ in range(N)]
def bfs(start,end):
deq = deque()
visited = [0 for i in range(N)]
deq.append(start)
while len(deq)!=0:
current = deq.popleft()
for i in range(N):
if(arr[current][i]==1 and visited[i]==0):
if(i == end):
print(1, end=" ")
return
visited[i] = 1
deq.append(i)
print(0, end=" ")
for i in range(N):
for j in range(N):
bfs(i, j)
print()