🕸️
그래프 기초
인접 리스트/행렬·방향/가중치
13강: 그래프 표현
그래프 입력을 빠르게 인접 리스트·행렬로 변환하는 정형 패턴을 익힙니다.
그래프인접 리스트인접 행렬
소요 시간
⏱ 약 45분
난이도
📊 중급
선수 조건
🎯 기초 트랙
결과물
그래프 입력을 빠르게 인접 리스트·행렬로 변환하는 정형 패턴을 익힙니다.
이 강의에서 배우는 것
- 1인접 리스트와 인접 행렬의 장단점을 설명하고 상황에 맞게 선택한다.
- 2방향/무방향, 가중/비가중 그래프를 코드로 표현한다.
- 3백준 스타일 입력(N 노드, M 간선)을 올바르게 파싱한다.
개요
💡
**Part 04 – 그래프 기초** | 난이도: ⭐⭐☆☆☆
소개: 그래프가 등장하는 백준 문제 유형들
그래프는 현실의 수많은 관계를 모델링합니다.
| 문제 유형 | 그래프 모델 | 대표 알고리즘 |
|---|---|---|
| 경로 탐색 | 간선 = 연결 | DFS / BFS |
| 최단 거리 | 간선 = 거리 | BFS / 다익스트라 |
| 선후 관계 | 방향 그래프 | 위상 정렬 |
| 연결 요소 | 무방향 그래프 | DFS / Union-Find |
| 네트워크 | 가중 방향 그래프 | 최대 유량 |
모든 그래프 문제의 첫 번째 단계는 **그래프를 올바르게 표현**하는 것입니다.
핵심 개념
인접 리스트 (Adjacency List)
text
그래프:
1 ─── 2
│ │
3 ─── 4
인접 리스트:
1: [2, 3]
2: [1, 4]
3: [1, 4]
4: [2, 3]- 공간: **O(V + E)**
- 특정 간선 존재 여부: O(degree) — 선형 탐색 필요
- 모든 인접 노드 탐색: O(degree) — 효율적
- **대부분의 그래프 문제에서 기본 선택**
인접 행렬 (Adjacency Matrix)
text
그래프:
1 ─── 2
│
3
인접 행렬 (V=4):
1 2 3 4
1 [0, 1, 1, 0]
2 [1, 0, 0, 0]
3 [1, 0, 0, 0]
4 [0, 0, 0, 0]- 공간: **O(V²)**
- 특정 간선 존재 여부: **O(1)**
- 모든 인접 노드 탐색: O(V)
- V ≤ 1000 이고 밀집 그래프(E ≈ V²)일 때 유리
공간 복잡도 비교
| V(노드 수) | E(간선 수) | 인접 리스트 | 인접 행렬 |
|---|---|---|---|
| 100 | 200 | O(300) | O(10,000) |
| 1,000 | 3,000 | O(4,000) | O(1,000,000) |
| 100,000 | 300,000 | O(400,000) | O(10¹⁰) — 불가 |
text-art 그래프 예시
text
방향 그래프 (Directed):
┌── 1 ──→ 2
│ │
│ ↓
└──→ 3 ──→ 4
무방향 그래프 (Undirected):
1 ─── 2
│ │
3 ─── 4 ─── 5
가중 그래프 (Weighted):
1 ──5── 2
│ │
3 7
│
2 ──── 3 ──1── 4예제로 보기
| 파일 | 내용 |
|---|---|
| `src/01_adjacency_list.py` | 리스트/딕셔너리 인접 리스트, 방향/무방향 |
| `src/02_adjacency_matrix.py` | 인접 행렬, 공간 분석, 언제 쓸까 |
| `src/03_weighted_graph.py` | 가중 인접 리스트, 간선 표현 |
| `src/04_graph_traversal_prep.py` | 백준 스타일 입력 파싱 |
자주 하는 실수 5가지
- **1-indexed vs 0-indexed 혼동** - 백준 문제는 대부분 노드 번호가 1부터 시작 - `graph = [[] for _ in range(n + 1)]` — 인덱스 1~n 사용 - 0번 인덱스는 사용하지 않음
- **무방향 그래프에서 간선을 한 방향만 추가** ```python # 잘못된 코드 graph[u].append(v) # u→v 만 추가 # 올바른 코드 graph[u].append(v) graph[v].append(u) # 양방향 모두 추가 ```
- **인접 행렬 크기를 n+1이 아닌 n으로 설정** - 1-indexed이면 `graph[n][n]` → `graph[n+1][n+1]`
- **가중 그래프에서 0 가중치를 연결 없음으로 착각** - 인접 행렬에서 0은 보통 "연결 없음" 의미 - 0 가중치 간선이 있다면 `float('inf')` 를 초기값으로 사용
- **자기 루프(self-loop) 처리 누락** - `u == v` 인 간선 입력이 올 때 무방향이면 한 번만 추가
정리
| 조건 | 추천 표현 |
|---|---|
| V, E 모두 큼 (일반적) | 인접 리스트 |
| 특정 간선 O(1) 조회 필요 | 인접 행렬 |
| V ≤ 1000, E ≈ V² | 인접 행렬 |
| 가중치 없음, 단순 연결 | `set` of sets |
| 동적 간선 추가/삭제 | 인접 리스트 (dict) |
직접 해 보기
- 위의 text-art 그래프를 인접 리스트로 코드에 표현하세요.
- 같은 그래프를 인접 행렬로도 표현하세요.
- V=5, E=7 인 무방향 그래프에서 인접 리스트와 인접 행렬의 메모리 사용량을 계산하세요.
과제
`homework/README.md` 참조