오일러 경로 / 회로
그래프의 모든 간선을 정확히 한 번씩 지나는 경로를 오일러 경로(Eulerian
trail), 시작점과 끝점이 같은 것을 오일러 회로(Eulerian circuit) 라 한다.
"한붓그리기"가 가능한가를 묻는 고전 문제다.
존재 조건
연결성(간선이 있는 정점들이 한 덩어리)을 전제로 한다.
무방향 그래프
| 종류 | 조건 |
|---|---|
| 오일러 회로 | 모든 정점의 차수가 짝수 |
| 오일러 경로 | 차수가 홀수인 정점이 정확히 0개 또는 2개 |
홀수 차수 정점이 2개면 그 둘이 각각 시작점과 끝점이 된다.
방향 그래프
| 종류 | 조건 |
|---|---|
| 오일러 회로 | 모든 정점에서 진입차수 = 진출차수 |
| 오일러 경로 | 한 정점만 (진출−진입 = 1), 한 정점만 (진입−진출 = 1), 나머지는 같음 |
왜 짝수 차수인가
회로가 어떤 정점을 지날 때마다 "들어오는 간선 하나, 나가는 간선 하나"를 짝지어
쓴다. 모든 간선을 정확히 한 번씩 쓰고 시작점으로 돌아오려면, 각 정점에서 쓰인
간선이 짝을 이뤄야 하므로 차수가 짝수여야 한다. 시작점과 끝점이 다른 경로라면
그 두 곳에서만 짝이 하나 어긋나므로 홀수 차수가 정확히 2개가 된다.
히어홀처 알고리즘
조건을 만족하면 다음 방식으로 실제 회로를 \(O(E)\)에 구성한다.
- 시작 정점에서 출발해 아직 안 쓴 간선을 따라 임의로 진행하다가 더 갈 수
없으면 멈춘다. 회로라면 이 막다른 곳은 반드시 출발점이다. - 만들어진 경로 위에서, 아직 안 쓴 간선이 남은 정점을 찾아 거기서 다시
같은 방식으로 작은 회로를 만들어 끼워 넣는다. - 모든 간선을 쓸 때까지 반복한다.
핵심 구현 트릭은 각 정점마다 "다음에 볼 간선 위치(포인터)"를 두어 같은 간선을
다시 보지 않게 하고, DFS 후위 순서로 정점을 스택에 쌓아 뒤집는 것이다.
이렇게 하면 끼워 넣기를 명시적으로 하지 않고도 올바른 순서가 나온다.
복잡도
각 간선을 정확히 한 번 소비하므로 \(O(V + E)\)다. 단, 무방향 그래프는 간선을
양끝에서 동시에 "사용됨" 표시해야 한다.