오랫만입니다. 가희와 함께 하는 3회 코딩 테스트 때문에 작년 연말부터 글이 꽤 뜸하게 올라왔습니다. 이것이 어제 끝났으니, 문제들을 하나 하나씩 리뷰해 보도록 하겠습니다. bfs나 dfs를 배우다 보면, 방향성이 없는 (다시 말해서, 양방향 간선만 있는) 그래프에서Component 라는 것이 나오게 됩니다. 이 문제가 대표적인 예입니다. 이것을 bfs나 dfs로 찾을 수 있다고 하는데요. 이것을 왜 찾을까, 찾아서 어디에 써 먹을 건지. 이 두 가지 의문에서 나온 것이 제가 출제한 가희와 베개 문제입니다. 아래 그림을 보면 Component는 2개가 있어요. 여기에 있는 간선들은 양방향으로 연결된 친구들입니다. 1번에서 bfs를 돌려 봅시다. 1번을 큐에 넣어볼까요? 그러면 큐에는 1만 들어가 있을 거..
BFS 검색 결과
가희와 거북이 인형은 그리 어렵지 않아 보이는 bfs, dfs입니다. 그런데, 거북이 컴포넌트가 최대 10^6-1개까지 올 수 있어서, 자칫하다가는 시간초과가 날 수 있습니다. 그래서, 1달 전에 여행가면서 예약했던 글에는 상대 속도의 개념을 이용하자는 내용이 있었습니다. [관련글] 상대 속도를 응용한 문제들을 풀어 봅시다. 그런데, 제가 설명을 누락한 부분이 있는데, 바로 bounding box 부분입니다. 예제를 가지고 설명해 보겠습니다. 우리는 거북이의 맨 위에, 맨 위에 있다면 가장 좌측에 있는 이 부분을 기준 좌표로 가지고 돌렸습니다. 거북이 컴포넌트들이 처음에 이 위치에 있다고 해 보겠습니다. 이 상태에서 오른쪽으로 거북이가 이동할 수 있을까요? 아닙니다. 이동하면, 컴포넌트 하나가 맵 바깥을..
백준에는 5214번 환승 문제와, 2021번 최소 환승 알고리즘을 구하는 문제가 있습니다. 이 두 문제 중에서 후자를 풀어보겠습니다. 역의 갯수 n과 노선 갯수 L은 둘 다 10만 이하라는 조건은 꽤 무시무시하게 다가옵니다. 각 노선 길이의 합은 100만을 넘지 않는다는 조건을 잘 이용해 봐야 할 듯 싶네요. 여기서 핵심은 '환승을 한다'는 것을 어떻게 그래프로 표현을 할 것인지입니다. 학교 과제에서도 왕왕 나오는 편이니, 이야기를 해 보도록 하겠습니다. 노선 1과 노선 2가 만나는 환승 역 j를 생각해 봅시다. 그래프는 요렇게 그려질 수 있습니다. 여기서 핵심은, j번 역을 통해서 노란색에서 파란색으로, 혹은 파란색에서 노란색 노선으로 건너갈 수 있다는 것입니다. 3개 노선이 만나는 j역이면 어떨까요?..
가중치가 0과 1만 있는 그래프에서 최단 거리는 어떻게 구할까요? 얼핏 들어서는 그냥 다익스트라를 잘 이용하면 될 거 같습니다. 그런데, deque나 Queue 구조만을 이용해서 코딩을 할 수 있습니다. 이게 어떻게 가능할까요? 먼저, 가중치는 0과 1만 있어요. 그리고 알고리즘 1은 위와 같습니다. 해석해 보면 그렇게 복잡하지 않아요. 시작 지점을 s라 합시다. 처음에는 s까지 최단 거리가 0이다. 라는 정보를 dq에 넣을 겁니다. 그리고, 자료 구조 dq의 앞 부분에서만 정보를 뺍니다. 이 정보는 to까지 min_dist가 cost다. 입니다. to와 인접한 지점을 a라 합시다. 이 때, to로부터 a까지 거리가 0이라면, a까지 거리에 대한 정보를 dq의 앞에 넣고, 아니라면 dq의 뒤에 넣습니다...
bfs는 뎁스가 깊어질수록 생성되는 state 수가 매우 많아집니다. 그러면, depth를 줄일 수만 있다면, 속도가 획기적으로 개선된다는 이야기 또한 됩니다. 시작점과 도착점에서 동시에 bfs를 하는 방식을 양방향 bfs라고 하는데요. 이렇게 하면, s에서 e로 가는 최적해가 2x일 때, s에서 x만큼, e에서 x만큼의 깊이만 탐색하면 됩니다. s에서만 출발하면 2x만큼 탐색하는 것에 비하면 거의 절반 가까이 줄어버린 셈입니다. 일단 어떤 식으로 탐색을 하는지 개략적으로 보고, 입문 문제를 풀어보도록 합시다. 백준에서 흔히 알려진, 루빅의 사각형은 구현이 안 되면 매우 힘든 문제이기 때문에, 입문 문제로 제외하였습니다. branch factor가 b라고 해 봅시다. 즉, 한 상태를 queue에서 뺐을 ..
최근댓글