그래프 탐색
연결 요소
섬이 몇 개인지 세기
노란 칸은 땅이고 빈 칸은 바다입니다. 땅이 이어진 덩어리가 섬이에요. 섬이 몇 개일지 먼저 고르고 땅을 눌러 섬을 하나씩 칠하며 세어 보세요.
노란 칸은 땅이고 빈 칸은 바다예요. 땅이 이어진 덩어리가 섬입니다. 섬이 모두 몇 개일까요?
센 섬 0개
내 예상 개 · 실제 3개 → 달랐어요
섬 1: 3칸 → 섬 2: 3칸 → 섬 3: 2칸땅 8칸을 칸마다 센 게 아니라 번지기를 시작한 횟수 3번을 셌습니다.
- 한 번 번지기 시작하면 — 이어진 땅이 모두 칠해졌다
- 섬 수 — 번지기를 새로 시작한 횟수와 같다
한 덩어리로 이어진 칸 묶음 = 연결 요소(connected component)
번지는 일은 앞에서 본 BFS(가까운 칸부터 한 겹씩)나 DFS(막다른 길까지 파고들기)가 합니다. 이 페이지 코드는 큐로 번지는 BFS 를 씁니다.
이어졌다는 건 위·아래·왼쪽·오른쪽이다
- 방금 겪은 대각선 — 대각선으로만 닿은 땅은 번지지 않았다. 그래서 다른 섬이다. 대각선까지 이으면 이 지도는 2개가 된다
- 센 땅은 표시해 둔다 — 칠한 땅을 또 만나도 세지 않아야 한다. 표시가 없으면 같은 섬을 두 번 센다
- 칸마다 한 번씩만 본다 — 칸이 N개면 걸리는 시간도 N에 비례한다. 100만 칸 지도도 직접 재 보니 1초쯤 걸렸다(Python 3.14, 컴퓨터마다 다르다)
코드는 땅을 만날 때마다 번지기를 한 번 시작한다
큐 = 먼저 넣은 게 먼저 나오는 줄. 위에서 번진 것과 같은 지도입니다. (r, c) 는 위에서 r번째 줄, 왼쪽에서 c번째 칸이고 0부터 셉니다.
다음을 눌러 한 줄씩 넘기며 칠해지는 칸과 큐를 보세요. 바다 칸은 건너뛰고 땅인 칸만 보여 줍니다.
센 섬 0개
땅땅땅땅땅땅땅땅
큐← 꺼낸다
- 비어 있음
다음을 눌러 한 줄씩 넘겨 보세요
count = 0 len(seen) = 0
count_islands.py
- 1from collections import deque
- 2
- 3def count_islands(grid):
- 4 rows, cols = len(grid), len(grid[0])
- 5 seen = set()
- 6 count = 0
- 7 for r in range(rows):
- 8 for c in range(cols):
- 9 if grid[r][c] == 1 and (r, c) not in seen:
- 10 count += 1
- 11 seen.add((r, c))
- 12 q = deque([(r, c)])
- 13 while q:
- 14 cr, cc = q.popleft()
- 15 for dr, dc in ((-1,0),(1,0),(0,-1),(0,1)):
- 16 nr, nc = cr + dr, cc + dc
- 17 if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1 and (nr, nc) not in seen:
- 18 seen.add((nr, nc))
- 19 q.append((nr, nc))
- 20 return count
0 / 32
seen— 이미 센 칸 모음. 칠하는 칸마다 여기에 넣는다count += 1— 안 센 땅을 만났을 때만 오른다. 새 섬이라는 뜻이다while q:— 큐가 빌 때까지 이웃 땅을 칠하며 번진다
대각선으로 닿은 땅도 이어진 것으로 세면(8방향) 이 지도의 섬은 몇 개일까요?
섬 세기에서 틀리는 자리
seen.add((nr, nc))를 지우면 — 큐가 끝나지 않는다. 두 칸이 서로를 번갈아 큐에 넣는다. 1000번을 꺼내도 계속 돌았다- 바깥
not in seen을 지우면 — 같은 섬의 칸마다 count 가 올라서 3이 아니라 8이 나온다 - 경계 검사를 지우면 — 통째로 지우면
IndexError: list index out of range가 난다.0 <=만 지우면 에러가 안 나서 더 위험하다. 음수 인덱스는 맨 뒤 칸을 읽고(grid[-1]은 맨 아래 줄), 이 지도에서는 우연히 답이 같았다 - 재귀로 번지면 — 100×100 지도가 전부 땅이면
RecursionError: maximum recursion depth exceeded가 난다. 같은 지도를 큐로 번지면 섬 1개로 끝난다 - 대각선까지 이으려면 — 이웃 방향 4개를 8개로 늘린다. 이 지도는 2개가 된다
문제에서 이 말이 보이면
덩어리가 몇 개인가섬·영역서로 이어진 것끼리 묶는다
다음 장에서는 길마다 걸리는 시간이 다를 때의 최단 거리, 다익스트라를 봅니다.