일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- enq: FB - contention
- git stash
- BFS
- 랜덤포레스트
- git 기본명령어
- Spark jdbc parallel read
- CF
- 통계분석
- eda
- Collaborative filtering
- Spark 튜닝
- Spark Data Read
- Oracle 논리적 저장 구조
- SQL
- Python
- 알고리즘
- Oracle ASSM
- 데이터분석
- 의사결정나무
- 추천시스템
- 앙상블
- git init
- 오라클 데이터 처리방식
- Decision Tree
- 배깅
- 네트워크
- 데이터 분석
- airflow 정리
- Linux
- 리눅스 환경변수
- Today
- Total
[Alex] 데이터 장인의 블로그
[알고리즘] BFS (너비 우선 탐색) / DFS (깊이 우선 탐색) 본문
개념 이해
그래프 탐색 : 어떤것들이 연속해서 이어질 때, 모두 확인하는 방법.
Graph : Vertex(어떤 것) + Edge(이어지는 것)
[그래프 탐색 종류]
BFS : 너비 우선 탐색 (Breadth-first search)
기준 노드(Vertex)에서 자식 노드(Vertex) 부터 탐색하는 방법.
즉, 주변에 분포해있는 노드부터 탐색하는 방법 (깊게 No, 넓게 Yes)
위의 그래프의 경우 탐색 차례 : 0 - 1 - 2 - 3 - 4 - 5 - 6
BFS = Queue 자료형과 맞음
DFS : 깊이 우선 탐색 (Depth-first search)
기준 노드(Vertex)에서 자식 노드(Vertex) -> 자식노드까지 탐색하는 방법.
즉, 자식의 자식까지(끝노드) 모두 탐색하는 방법 (깊게 Yes, 넓게 No)
위의 그래프의 경우 탐색 차례 : 0 - 1 - 3 - 4 - 2 - 5 - 6
DFS = Stack 자료형과 맞음
문제 풀이 [출처 : 백준]
https://www.acmicpc.net/problem/1926
어떤 큰 도화지에 그림이 그려져 있을 때, 그 그림의 개수와, 그 그림 중 넓이가 가장 넓은 것의 넓이를 출력하여라. 단, 그림이라는 것은 1로 연결된 것을 한 그림이라고 정의하자. 가로나 세로로 연결된 것은 연결이 된 것이고 대각선으로 연결이 된 것은 떨어진 그림이다. 그림의 넓이란 그림에 포함된 1의 개수이다.
요약하자면,
- 그림의 개수와, 그 그림 중 넓이가 가장 넓은 것의 넓이를 출력하는 문제
- 모든 부분을 탐색해야 되기 때문에 BFS로 풀이
- 이어져 있는 부분은 count 변수로 카운트해주고 paint 배열에 append
- 그림의 개수는 len(paint), 가장 넓은 그림은 max(paint)
BFS로 이 문제를 푼다면
1. BFS 로 1의 위치를 찾는다.
2. 이중 For문을 돌리면서 1이 나올때 BFS를 수행한다.
2 - 1. 1이 있었던 좌표를 기준으로 (상, 하, 좌, 우) 차례대로 탐지를 해나간다. 만약 좌표 기준으로 주변에 1이 있는 경우는 count += 1 로 업데이트 후 0으로 변경. (확인 완료 표시)
2 - 2. 2-1에서 1로 탐지했던 좌표를 다음 탐지 대상으로 추가하기 위해서 Queue에 입력.
from collections import deque
n, m = map(int, input().split())
graph = []
for i in range(n):
graph.append(list(map(int, input().split())))
# 차례대로
# 아래, 위, 오른쪽, 왼쪽 이동 좌표
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]
def bfs(graph, a, b):
queue = deque()
queue.append((a, b))
graph[a][b] = 0
count = 1
while queue:
x, y = queue.popleft() # 큐의 특성인 '선입선출'을 표현하기 위해서 사용.
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx < 0 or nx >= n or ny < 0 or ny >= m: # 더 이상 이동할 공간이 없는 경우는 제외하고 탐지.
continue
if graph[nx][ny] == 1:
graph[nx][ny] = 0 # 기존의 graph 변수에서 확인을 마쳤다는 표시로 1 -> 0으로 변경
queue.append((nx, ny))
count += 1
return count
paint = []
for i in range(n):
for j in range(m):
if graph[i][j] == 1:
paint.append(bfs(graph, i, j))
if len(paint) == 0:
print(len(paint))
print(0)
else:
print(len(paint))
print(max(paint))
'알고리즘' 카테고리의 다른 글
[알고리즘] BFS - 문제풀이 (백준 - 1261번) (0) | 2022.07.10 |
---|---|
[알고리즘] 5) 병합 정렬 알고리즘 (0) | 2022.06.26 |
[알고리즘] 4) 퀵 정렬 알고리즘 (0) | 2022.06.26 |
[알고리즘] 3) 삽입 정렬 알고리즘 (0) | 2022.06.26 |
[알고리즘] 2) 버블 정렬 알고리즘 (0) | 2022.06.26 |