일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Django의 편의성
- 시간복잡도
- 입출력 패턴
- 자료구조
- string 메소드
- double ended queue
- UI한글변경
- getline
- c++
- 백준
- Django Nodejs 차이점
- 입/출력
- vscode
- 연결요소
- iOS14
- 구조체와 클래스의 공통점 및 차이점
- 알고리즘 공부방법
- 엑셀
- 프레임워크와 라이브러리의 차이
- 장고란
- 매크로
- 2557
- string 함수
- scanf
- 이분그래프
- EOF
- correlation coefficient
- 표준 입출력
- k-eta
- Django란
- Today
- Total
Storage Gonie
챕터6-5. 그래프 | 문제풀이(2) - 플러드필 알고리즘(DFS, BFS 탐색응용) 본문
챕터6-5. 그래프 | 문제풀이(2) - 플러드필 알고리즘(DFS, BFS 탐색응용)
Storage Gonie 2019. 5. 29. 11:34플러드필 알고리즘
- 어떤 배열을 채우는 알고리즘이며, 어떤 위치와 연결된 모든 위치를 찾는 알고리즘이다.
- dx, dy 가 사용됨.
유형1. 동시에 진행되는 탐색이 1개뿐인 것
# 단지에 번호를 붙이는 문제
- https://www.acmicpc.net/problem/2667
- 문제요약 :
정사각형 모양의 지도가 주어지는데, 0은 집이 없는 곳이고 1은 집이 있는 곳이다.
이 때 지도를 보고, 연결된 집의 모임 각각에 번호를 붙이려고 한다.
현재 위치를 기준으로 좌, 우, 아래, 위 중 한 곳이라도 집이 있다면 연결되었다고 할 수 있다.
- 이 문제는 (x, y)형태로 값이 주어지지만, 이 값들을 그래프로 보면 연결요소의 개수를 구하는 것과 같다.
BFS 혹은 DFS를 이용해서 탐색을 수행하는 것을 통해 해결할 수 있는 문제이다.
- check[i][j] = "(i, j)를 방문 안했다면 0, 방문 했다면 단지번호"를 이용해 해결할 수 있음.
- 인접행렬이나 인접리스트를 만들 필요는 없다. 그 이유는
간선으로 연결된 정점은 좌, 위, 우, 아래 중 한 칸이기 때문에 모든 칸 마다 4개의 칸을 검사하면 되기 때문이다.
- 모든 땅에 번호를 매기는 것을 완료하였다면, 그 번호들을 각각 카운트 해준다.
이는 ans[땅에 매겨진번호] += 1을 함으로써 수행할 수 있다.
* 자주 실수하는 부분
- dx, dy는 동시에 같은 인덱스만 뽑아써야 한다는 것을 상기해두자.
- ans 배열에서 맨 앞의 0은 사용하지 않았으므로 sort(ans+1, ans+cnt+1) 처럼 +1 해주는 것을 잊으면 안된다.
- DFS, BFS 두려워하지 마라.
check배열을 사용해 중복방문은 하지않으며, 간선이 있으면 가는거고 아니면 안가는 거라고 간단히 생각하자.
# 섬의 개수를 구하는 문제
- https://www.acmicpc.net/problem/4963
- 바로 위의 문제와 비슷한 문제인데, 차이점은 연결의 범위가 대각선 방향도 포함된다는 것이다.
이것은 아래와 같이 방향을 4개 더 추가해줌으로써 해결이 가능해진다.
- 주의할 점은 이중 for문 사용할 때 i는 h이고, j는 w이라는 점이다.
# 미로탐색, (1, 1) 에서 (N, M)으로 가는 가장 빠른 거리를 구하는 문제
- https://www.acmicpc.net/problem/2178
- 가장 빠른 길을 구하는(최단경로) 문제 이므로 BFS 탐색만 사용이 가능하다.
BFS 탐색은 모든 가중치가 1이면 최단거리 경로를 찾을 수 있다.
- dist[i][j] = "방문여부 및 (1, 1)부터 (i, j)까지의 거리"
dist[next] = dist[now] + 1 이 방식으로 모든 탐색가능한 정점에 거리를 구해주면 최단거리를 구할 수 있음.
BFS탐색으로 모든 점에 대한 dist를 구한 뒤 dist[m-1][n-1]를 출력해주면됨.
유형2. 동시에 진행되는 탐색이 2개이상인 것
# 토마토
- https://www.acmicpc.net/problem/7576
- 미로탐색 문제와 똑같은 방식으로 풀면 되지만, 이 문제는 탐색이 여러군데서 동시에 단계적으로 진행된다는 다른 특징을 가진다.
- 시작점이 여러개이고, 그 점들에 대해서 동시에 BFS를 진행시켜야 한다면, 그 시작점들을 모두 큐에 넣고 탐색을 시작하면 된다.
- 사용되는 변수를 줄이고 싶다면 dist 배열을 -1로 초기화 하여 방문하지 않은 경우를 -1로 표시해주고,
0이상이면 방문했고 익은 토마토로부터의 거리를 의미하도록한다.
# 여러 섬으로 이루어진 나라에서 두 섬을 연결하는 가장 짧은 다리를 찾는 문제
- https://www.acmicpc.net/problem/2146
@ 방법1(느림)
- 단지번호붙이기 + 토마토 문제 처럼 먼저 섬을 그룹으로 나누어 group[i][j] = (i, j)의 그룹번호를 매긴다.
- 그 다음 각각의 그룹에 대해서 BFS탐색을 이용해 모든 땅에대한 거리를 계산한다.
이 때 해당 그룹에서 다른 땅까지의 최단거리는 그룹번호가 다른 곳의 거리값을 보면 된다. 그중 가장 작은 값을 선택.
- 이 방법은 각각의 그룹에 대해서 BFS 알고리즘을 수행해야 하기 때문에 느리다.
@ 방법2(빠름)
- 이 방식은 위의 방식과 다르게 각 그룹마다 dist를 구하기 위해 했던 작업이 없어진다.
- 단지번호붙이기 + 토마토 문제 처럼 먼저 섬을 그룹으로 나누어 g[i][j] = (i, j)의 그룹번호를 매긴다.
- 그룹번호와 거리 두가지를 각각 BFS 탐색으로 확장시킨다.
- 확장시킨 배열에서 인접한 칸인데, 다른 그룹번호를 가진다면 이는 다리가 놓일 수 있는 위치이며,
다리의 길이는 인접한 두 칸이 가진 dist값을 합한 값임.
이 값들 중 가장 작은 값을 찾으면 됨.
'알고리즘 > 알고리즘 기초(코드플러스)' 카테고리의 다른 글
챕터7-2. 트리 | 순회방법(전위, 중위, 후위) (0) | 2019.05.29 |
---|---|
챕터7-1. 트리 | 개념 및 저장방법 (0) | 2019.05.29 |
챕터6-4. 그래프 | 문제풀이(1) - DFS, BFS 탐색응용 (0) | 2019.05.27 |
챕터6-3. 그래프 | 그래프의 탐색(DFS, BFS) (0) | 2019.05.22 |
챕터6-2. 그래프 | 그래프의 표현 및 저장하는 방법 (0) | 2019.05.21 |