μœ„μƒ μ •λ ¬ (Topological Sort)

μœ„μƒ μ •λ ¬ (Topological Sort)

κ°œμš”

μœ„μƒ 정렬은 λ°©ν–₯ λΉ„μˆœν™˜ κ·Έλž˜ν”„(DAG)의 정점듀을 μ„ ν˜•μœΌλ‘œ μ •λ ¬ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μž…λ‹ˆλ‹€. λͺ¨λ“  κ°„μ„  (u, v)에 λŒ€ν•΄ uκ°€ v보닀 λ¨Όμ € λ‚˜νƒ€λ‚˜λ„λ‘ μ •λ ¬ν•©λ‹ˆλ‹€.


λͺ©μ°¨

  1. μœ„μƒ μ •λ ¬ κ°œλ…
  2. Kahn μ•Œκ³ λ¦¬μ¦˜ (BFS)
  3. DFS 기반 μœ„μƒ μ •λ ¬
  4. 사이클 탐지
  5. ν™œμš© 문제
  6. μ—°μŠ΅ 문제

1. μœ„μƒ μ •λ ¬ κ°œλ…

1.1 DAG (Directed Acyclic Graph)

DAG: λ°©ν–₯ λΉ„μˆœν™˜ κ·Έλž˜ν”„
- λ°©ν–₯ 간선을 가짐
- 사이클이 μ—†μŒ

μœ„μƒ 정렬이 κ°€λŠ₯ν•œ 쑰건: κ·Έλž˜ν”„κ°€ DAG

μ˜ˆμ‹œ: μˆ˜κ°• μ‹ μ²­

κ³Όλͺ©A β†’ κ³Όλͺ©B β†’ κ³Όλͺ©D
  ↓       ↓
κ³Όλͺ©C β†’ κ³Όλͺ©E

μœ νš¨ν•œ μˆ˜κ°• μˆœμ„œ:
A β†’ B β†’ C β†’ D β†’ E  λ˜λŠ”
A β†’ C β†’ B β†’ D β†’ E  λ˜λŠ”
A β†’ C β†’ B β†’ E β†’ D

1.2 μ§„μž… μ°¨μˆ˜μ™€ μ§„μΆœ 차수

μ§„μž… 차수 (In-degree): μ •μ μœΌλ‘œ λ“€μ–΄μ˜€λŠ” κ°„μ„  수
μ§„μΆœ 차수 (Out-degree): μ •μ μ—μ„œ λ‚˜κ°€λŠ” κ°„μ„  수

μ˜ˆμ‹œ:
    A β†’ B
    ↓   ↓
    C β†’ D

정점 | μ§„μž… | μ§„μΆœ
-----|------|------
  A  |   0  |   2
  B  |   1  |   1
  C  |   1  |   1
  D  |   2  |   0

μ§„μž… μ°¨μˆ˜κ°€ 0인 정점: μ‹œμž‘μ  (μ˜μ‘΄μ„± μ—†μŒ)

1.3 μœ„μƒ μˆœμ„œμ˜ νŠΉμ„±

- μ—¬λŸ¬ μœ„μƒ μˆœμ„œκ°€ μ‘΄μž¬ν•  수 있음
- DAGμ—μ„œλ§Œ μœ„μƒ μ •λ ¬ κ°€λŠ₯
- 사이클 쑴재 μ‹œ μœ„μƒ μ •λ ¬ λΆˆκ°€λŠ₯

μœ„μƒ μ •λ ¬ μ•Œκ³ λ¦¬μ¦˜:
1. Kahn μ•Œκ³ λ¦¬μ¦˜ (BFS) - O(V + E)
2. DFS 기반 - O(V + E)

2. Kahn μ•Œκ³ λ¦¬μ¦˜ (BFS)

2.1 μ•Œκ³ λ¦¬μ¦˜ 원리

1. λͺ¨λ“  μ •μ μ˜ μ§„μž… 차수 계산
2. μ§„μž… μ°¨μˆ˜κ°€ 0인 정점을 큐에 μ‚½μž…
3. νμ—μ„œ 정점을 κΊΌλ‚΄ 결과에 μΆ”κ°€
4. ν•΄λ‹Ή μ •μ μ—μ„œ λ‚˜κ°€λŠ” κ°„μ„  제거 (인접 정점 μ§„μž… 차수 κ°μ†Œ)
5. μƒˆλ‘œ μ§„μž… μ°¨μˆ˜κ°€ 0이 된 정점을 큐에 μ‚½μž…
6. 큐가 빌 λ•ŒκΉŒμ§€ 반볡

μ‹œκ°ν™”:
초기: in_degree = [0, 1, 1, 2]
      A(0) β†’ B(1) β†’ D(2)
        ↓      ↓
       C(1) β†β”€β”€β”˜

단계 1: A 선택 (μ§„μž…μ°¨μˆ˜ 0)
        큐: [A], 결과: [A]
        B, C의 μ§„μž…μ°¨μˆ˜ κ°μ†Œ β†’ B(0), C(0)

단계 2: B 선택 (λ˜λŠ” C)
        큐: [B, C], 결과: [A, B]
        D의 μ§„μž…μ°¨μˆ˜ κ°μ†Œ β†’ D(1)

단계 3: C 선택
        큐: [C], 결과: [A, B, C]
        D의 μ§„μž…μ°¨μˆ˜ κ°μ†Œ β†’ D(0)

단계 4: D 선택
        큐: [D], 결과: [A, B, C, D]

μ΅œμ’…: [A, B, C, D]

2.2 κ΅¬ν˜„

from collections import deque

def topological_sort_kahn(n, edges):
    """
    Kahn μ•Œκ³ λ¦¬μ¦˜ (BFS 기반 μœ„μƒ μ •λ ¬)
    n: 정점 수 (0λΆ€ν„° n-1)
    edges: [(u, v), ...] u β†’ v κ°„μ„ 
    μ‹œκ°„: O(V + E)
    """
    # κ·Έλž˜ν”„ ꡬ성 및 μ§„μž… 차수 계산
    graph = [[] for _ in range(n)]
    in_degree = [0] * n

    for u, v in edges:
        graph[u].append(v)
        in_degree[v] += 1

    # μ§„μž… μ°¨μˆ˜κ°€ 0인 μ •μ λ“€λ‘œ μ‹œμž‘
    queue = deque()
    for i in range(n):
        if in_degree[i] == 0:
            queue.append(i)

    result = []

    while queue:
        node = queue.popleft()
        result.append(node)

        for neighbor in graph[node]:
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                queue.append(neighbor)

    # 사이클 확인
    if len(result) != n:
        return []  # 사이클 쑴재

    return result


# μ˜ˆμ‹œ
n = 6
edges = [(5, 2), (5, 0), (4, 0), (4, 1), (2, 3), (3, 1)]
print(topological_sort_kahn(n, edges))  # [4, 5, 2, 0, 3, 1] λ˜λŠ” λ‹€λ₯Έ μœ νš¨ν•œ μˆœμ„œ

2.3 C++ κ΅¬ν˜„

#include <vector>
#include <queue>
using namespace std;

vector<int> topologicalSortKahn(int n, vector<pair<int, int>>& edges) {
    vector<vector<int>> graph(n);
    vector<int> inDegree(n, 0);

    for (auto& [u, v] : edges) {
        graph[u].push_back(v);
        inDegree[v]++;
    }

    queue<int> q;
    for (int i = 0; i < n; i++) {
        if (inDegree[i] == 0) {
            q.push(i);
        }
    }

    vector<int> result;

    while (!q.empty()) {
        int node = q.front();
        q.pop();
        result.push_back(node);

        for (int neighbor : graph[node]) {
            if (--inDegree[neighbor] == 0) {
                q.push(neighbor);
            }
        }
    }

    if (result.size() != n) {
        return {};  // 사이클 쑴재
    }

    return result;
}

3. DFS 기반 μœ„μƒ μ •λ ¬

3.1 μ•Œκ³ λ¦¬μ¦˜ 원리

1. λͺ¨λ“  정점에 λŒ€ν•΄ DFS μˆ˜ν–‰
2. DFSκ°€ λλ‚˜λŠ” μˆœμ„œλŒ€λ‘œ μŠ€νƒμ— μ‚½μž…
3. μŠ€νƒμ„ μ—­μˆœμœΌλ‘œ 좜λ ₯

아이디어:
- DFSμ—μ„œ 정점 v의 탐색이 λλ‚˜λ©΄ vμ—μ„œ 갈 수 μžˆλŠ” λͺ¨λ“  정점은 이미 처리됨
- λ”°λΌμ„œ μŠ€νƒμ— 늦게 λ“€μ–΄κ°„ 정점이 μœ„μƒ μˆœμ„œμƒ λ¨Όμ € 와야 함

μ‹œκ°ν™”:
    A β†’ B β†’ D
    ↓
    C

DFS λ°©λ¬Έ μˆœμ„œ: A β†’ B β†’ D(μ™„λ£Œ) β†’ B(μ™„λ£Œ) β†’ C(μ™„λ£Œ) β†’ A(μ™„λ£Œ)
μŠ€νƒ (μ™„λ£Œ 순): [D, B, C, A]
κ²°κ³Ό (μ—­μˆœ): [A, C, B, D] λ˜λŠ” [A, B, D, C]

3.2 κ΅¬ν˜„

def topological_sort_dfs(n, edges):
    """
    DFS 기반 μœ„μƒ μ •λ ¬
    μ‹œκ°„: O(V + E)
    """
    graph = [[] for _ in range(n)]
    for u, v in edges:
        graph[u].append(v)

    visited = [0] * n  # 0: λ―Έλ°©λ¬Έ, 1: λ°©λ¬Έ 쀑, 2: μ™„λ£Œ
    result = []
    has_cycle = False

    def dfs(node):
        nonlocal has_cycle
        if has_cycle:
            return

        visited[node] = 1  # λ°©λ¬Έ 쀑

        for neighbor in graph[node]:
            if visited[neighbor] == 1:
                # λ°©λ¬Έ 쀑인 λ…Έλ“œλ₯Ό λ‹€μ‹œ λ§Œλ‚¨ β†’ 사이클
                has_cycle = True
                return
            if visited[neighbor] == 0:
                dfs(neighbor)

        visited[node] = 2  # μ™„λ£Œ
        result.append(node)

    for i in range(n):
        if visited[i] == 0:
            dfs(i)

    if has_cycle:
        return []

    return result[::-1]  # μ—­μˆœ


# μ˜ˆμ‹œ
n = 6
edges = [(5, 2), (5, 0), (4, 0), (4, 1), (2, 3), (3, 1)]
print(topological_sort_dfs(n, edges))  # [5, 4, 2, 3, 1, 0] λ˜λŠ” λ‹€λ₯Έ μœ νš¨ν•œ μˆœμ„œ

3.3 μŠ€νƒ μ‚¬μš© (λΉ„μž¬κ·€)

def topological_sort_iterative(n, edges):
    """반볡적 DFS μœ„μƒ μ •λ ¬"""
    graph = [[] for _ in range(n)]
    for u, v in edges:
        graph[u].append(v)

    visited = [False] * n
    result = []

    for start in range(n):
        if visited[start]:
            continue

        stack = [(start, False)]  # (λ…Έλ“œ, 처리 μ™„λ£Œ μ—¬λΆ€)

        while stack:
            node, processed = stack.pop()

            if processed:
                result.append(node)
                continue

            if visited[node]:
                continue

            visited[node] = True
            stack.append((node, True))  # μ™„λ£Œ 처리λ₯Ό μœ„ν•΄ λ‹€μ‹œ μ‚½μž…

            for neighbor in graph[node]:
                if not visited[neighbor]:
                    stack.append((neighbor, False))

    return result[::-1]

4. 사이클 탐지

4.1 Kahn μ•Œκ³ λ¦¬μ¦˜μ—μ„œμ˜ 사이클 탐지

def has_cycle_kahn(n, edges):
    """
    μœ„μƒ μ •λ ¬ 결과의 길이가 n보닀 μž‘μœΌλ©΄ 사이클 쑴재
    """
    result = topological_sort_kahn(n, edges)
    return len(result) != n

# 사이클이 μžˆλŠ” 경우
edges_with_cycle = [(0, 1), (1, 2), (2, 0)]  # 0 β†’ 1 β†’ 2 β†’ 0
print(has_cycle_kahn(3, edges_with_cycle))  # True

4.2 DFS 색상 기반 사이클 탐지

def has_cycle_dfs(n, edges):
    """
    DFS 색상 κΈ°λ²•μœΌλ‘œ 사이클 탐지
    WHITE(0): λ―Έλ°©λ¬Έ
    GRAY(1): λ°©λ¬Έ 쀑 (μž¬κ·€ μŠ€νƒμ— 있음)
    BLACK(2): μ™„λ£Œ
    """
    graph = [[] for _ in range(n)]
    for u, v in edges:
        graph[u].append(v)

    WHITE, GRAY, BLACK = 0, 1, 2
    color = [WHITE] * n

    def dfs(node):
        color[node] = GRAY

        for neighbor in graph[node]:
            if color[neighbor] == GRAY:
                return True  # 사이클 발견
            if color[neighbor] == WHITE:
                if dfs(neighbor):
                    return True

        color[node] = BLACK
        return False

    for i in range(n):
        if color[i] == WHITE:
            if dfs(i):
                return True

    return False

4.3 사이클 경둜 μ°ΎκΈ°

def find_cycle(n, edges):
    """사이클이 μžˆλ‹€λ©΄ 사이클 경둜 λ°˜ν™˜"""
    graph = [[] for _ in range(n)]
    for u, v in edges:
        graph[u].append(v)

    WHITE, GRAY, BLACK = 0, 1, 2
    color = [WHITE] * n
    parent = [-1] * n

    def dfs(node):
        color[node] = GRAY

        for neighbor in graph[node]:
            if color[neighbor] == GRAY:
                # 사이클 발견! 경둜 볡원
                cycle = [neighbor]
                curr = node
                while curr != neighbor:
                    cycle.append(curr)
                    curr = parent[curr]
                cycle.append(neighbor)
                return cycle[::-1]

            if color[neighbor] == WHITE:
                parent[neighbor] = node
                result = dfs(neighbor)
                if result:
                    return result

        color[node] = BLACK
        return None

    for i in range(n):
        if color[i] == WHITE:
            result = dfs(i)
            if result:
                return result

    return None

# μ˜ˆμ‹œ
edges = [(0, 1), (1, 2), (2, 3), (3, 1)]  # 1 β†’ 2 β†’ 3 β†’ 1 사이클
print(find_cycle(4, edges))  # [1, 2, 3, 1]

5. ν™œμš© 문제

5.1 μˆ˜κ°• μ‹ μ²­ (κΈ°λ³Έ)

def can_finish(num_courses, prerequisites):
    """
    λͺ¨λ“  κ³Όλͺ©μ„ μˆ˜κ°•ν•  수 μžˆλŠ”μ§€ 확인
    prerequisites[i] = [a, b] : bλ₯Ό λ¨Όμ € λ“€μ–΄μ•Ό aλ₯Ό 듀을 수 있음
    """
    result = topological_sort_kahn(num_courses,
                                    [(b, a) for a, b in prerequisites])
    return len(result) == num_courses

# LeetCode 207. Course Schedule
print(can_finish(2, [[1, 0]]))  # True: 0 β†’ 1
print(can_finish(2, [[1, 0], [0, 1]]))  # False: 사이클

5.2 μˆ˜κ°• μˆœμ„œ μ°ΎκΈ°

def find_order(num_courses, prerequisites):
    """
    κ°€λŠ₯ν•œ μˆ˜κ°• μˆœμ„œ λ°˜ν™˜
    λΆˆκ°€λŠ₯ν•˜λ©΄ 빈 리슀트 λ°˜ν™˜
    """
    return topological_sort_kahn(num_courses,
                                  [(b, a) for a, b in prerequisites])

# LeetCode 210. Course Schedule II
print(find_order(4, [[1, 0], [2, 0], [3, 1], [3, 2]]))
# [0, 1, 2, 3] λ˜λŠ” [0, 2, 1, 3]

5.3 λΉŒλ“œ μˆœμ„œ

def build_order(projects, dependencies):
    """
    ν”„λ‘œμ νŠΈ λΉŒλ“œ μˆœμ„œ κ²°μ •
    dependencies: [(a, b), ...] - bλ₯Ό λΉŒλ“œν•œ ν›„ aλ₯Ό λΉŒλ“œ
    """
    # ν”„λ‘œμ νŠΈ 이름 β†’ 인덱슀 λ§€ν•‘
    proj_to_idx = {p: i for i, p in enumerate(projects)}
    n = len(projects)

    edges = [(proj_to_idx[b], proj_to_idx[a]) for a, b in dependencies]
    order = topological_sort_kahn(n, edges)

    if not order:
        return None  # μˆœν™˜ μ˜μ‘΄μ„±

    return [projects[i] for i in order]

# μ˜ˆμ‹œ
projects = ['a', 'b', 'c', 'd', 'e', 'f']
dependencies = [('a', 'd'), ('f', 'b'), ('b', 'd'), ('f', 'a'), ('d', 'c')]
print(build_order(projects, dependencies))  # ['e', 'f', 'c', 'b', 'd', 'a'] λ“±

5.4 μž‘μ—… μŠ€μΌ€μ€„λ§ (κ°€μž₯ λΉ λ₯Έ μ™„λ£Œ μ‹œκ°„)

def earliest_completion(n, edges, times):
    """
    각 μž‘μ—…μ˜ κ°€μž₯ λΉ λ₯Έ μ™„λ£Œ μ‹œκ°„ 계산
    edges: [(u, v), ...] u μ™„λ£Œ ν›„ v μ‹œμž‘ κ°€λŠ₯
    times[i]: μž‘μ—… i의 μ†Œμš” μ‹œκ°„
    """
    from collections import deque

    graph = [[] for _ in range(n)]
    in_degree = [0] * n

    for u, v in edges:
        graph[u].append(v)
        in_degree[v] += 1

    # earliest[i] = μž‘μ—… i의 κ°€μž₯ λΉ λ₯Έ μ‹œμž‘ μ‹œκ°„
    earliest = [0] * n

    queue = deque()
    for i in range(n):
        if in_degree[i] == 0:
            queue.append(i)

    while queue:
        node = queue.popleft()

        for neighbor in graph[node]:
            # neighbor의 μ‹œμž‘ μ‹œκ°„ κ°±μ‹ 
            earliest[neighbor] = max(earliest[neighbor],
                                      earliest[node] + times[node])
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                queue.append(neighbor)

    # μ™„λ£Œ μ‹œκ°„ 계산
    completion = [earliest[i] + times[i] for i in range(n)]
    return completion, max(completion)

# μ˜ˆμ‹œ
n = 4
edges = [(0, 2), (1, 2), (2, 3)]
times = [3, 2, 5, 4]
completion, total = earliest_completion(n, edges, times)
print(f"μ™„λ£Œ μ‹œκ°„: {completion}")  # [3, 2, 8, 12]
print(f"전체 μ†Œμš”: {total}")  # 12

5.5 사전 순 κ°€μž₯ λΉ λ₯Έ μœ„μƒ μˆœμ„œ

import heapq

def lexicographic_topological_sort(n, edges):
    """
    사전 순으둜 κ°€μž₯ λΉ λ₯Έ μœ„μƒ μˆœμ„œ
    μ΅œμ†Œ νž™ μ‚¬μš©
    """
    graph = [[] for _ in range(n)]
    in_degree = [0] * n

    for u, v in edges:
        graph[u].append(v)
        in_degree[v] += 1

    # μ΅œμ†Œ νž™ μ‚¬μš©
    heap = []
    for i in range(n):
        if in_degree[i] == 0:
            heapq.heappush(heap, i)

    result = []

    while heap:
        node = heapq.heappop(heap)
        result.append(node)

        for neighbor in graph[node]:
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                heapq.heappush(heap, neighbor)

    return result if len(result) == n else []

# μ˜ˆμ‹œ
n = 4
edges = [(0, 1), (0, 2), (1, 3), (2, 3)]
print(lexicographic_topological_sort(n, edges))  # [0, 1, 2, 3]

5.6 μœ„μƒ μ •λ ¬ 경둜의 수

def count_topological_sorts(n, edges):
    """
    κ°€λŠ₯ν•œ μœ„μƒ μ •λ ¬μ˜ 수 (λ°±νŠΈλž˜ν‚Ή)
    주의: μ§€μˆ˜μ  μ‹œκ°„ λ³΅μž‘λ„
    """
    graph = [[] for _ in range(n)]
    in_degree = [0] * n

    for u, v in edges:
        graph[u].append(v)
        in_degree[v] += 1

    count = 0

    def backtrack(path):
        nonlocal count

        if len(path) == n:
            count += 1
            return

        for i in range(n):
            if i not in path and in_degree[i] == 0:
                # 선택
                for neighbor in graph[i]:
                    in_degree[neighbor] -= 1
                path.add(i)

                backtrack(path)

                # 볡원
                path.remove(i)
                for neighbor in graph[i]:
                    in_degree[neighbor] += 1

    backtrack(set())
    return count

# μ˜ˆμ‹œ (μž‘μ€ nμ—μ„œλ§Œ μ‚¬μš©)
n = 4
edges = [(0, 1), (0, 2), (1, 3), (2, 3)]
print(count_topological_sorts(n, edges))  # 2: [0,1,2,3], [0,2,1,3]

5.7 Alien Dictionary

def alien_order(words):
    """
    외계어 μ•ŒνŒŒλ²³ μˆœμ„œ μΆ”λ‘ 
    words: 사전 순으둜 μ •λ ¬λœ 외계어 단어 λͺ©λ‘
    """
    from collections import defaultdict

    # λͺ¨λ“  문자 μˆ˜μ§‘
    chars = set()
    for word in words:
        chars.update(word)

    graph = defaultdict(set)
    in_degree = {c: 0 for c in chars}

    # μΈμ ‘ν•œ 단어듀을 λΉ„κ΅ν•˜μ—¬ μˆœμ„œ μΆ”λ‘ 
    for i in range(len(words) - 1):
        w1, w2 = words[i], words[i + 1]

        # μ˜ˆμ™Έ: w1이 w2의 접두사인데 더 κΈΈλ©΄ λΆˆκ°€λŠ₯
        if len(w1) > len(w2) and w1.startswith(w2):
            return ""

        for c1, c2 in zip(w1, w2):
            if c1 != c2:
                if c2 not in graph[c1]:
                    graph[c1].add(c2)
                    in_degree[c2] += 1
                break

    # μœ„μƒ μ •λ ¬
    from collections import deque
    queue = deque([c for c in chars if in_degree[c] == 0])
    result = []

    while queue:
        c = queue.popleft()
        result.append(c)

        for neighbor in graph[c]:
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                queue.append(neighbor)

    if len(result) != len(chars):
        return ""  # 사이클 (λΆˆκ°€λŠ₯ν•œ μž…λ ₯)

    return "".join(result)

# LeetCode 269. Alien Dictionary
words = ["wrt", "wrf", "er", "ett", "rftt"]
print(alien_order(words))  # "wertf"

6. μ—°μŠ΅ 문제

μΆ”μ²œ 문제

λ‚œμ΄λ„ 문제 ν”Œλž«νΌ μœ ν˜•
⭐⭐ 쀄 μ„Έμš°κΈ° λ°±μ€€ κΈ°λ³Έ μœ„μƒμ •λ ¬
⭐⭐ Course Schedule LeetCode 사이클 탐지
⭐⭐ Course Schedule II LeetCode μœ„μƒμ •λ ¬ μˆœμ„œ
⭐⭐⭐ μž‘μ—… λ°±μ€€ μ΅œμ†Œ μ‹œκ°„
⭐⭐⭐ κ²Œμž„ 개발 λ°±μ€€ μž‘μ—… μŠ€μΌ€μ€„λ§
⭐⭐⭐ λ¬Έμ œμ§‘ λ°±μ€€ 사전 순 μœ„μƒμ •λ ¬
⭐⭐⭐⭐ Alien Dictionary LeetCode μˆœμ„œ μΆ”λ‘ 

μ•Œκ³ λ¦¬μ¦˜ 비ꡐ

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ μ•Œκ³ λ¦¬μ¦˜         β”‚ μ‹œκ°„        β”‚ 곡간        β”‚ νŠΉμ§•                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Kahn (BFS)      β”‚ O(V + E)    β”‚ O(V)        β”‚ μ§„μž…μ°¨μˆ˜ 기반       β”‚
β”‚ DFS 기반        β”‚ O(V + E)    β”‚ O(V)        β”‚ μ’…λ£Œ μ—­μˆœ          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 사전 순 (νž™)     β”‚ O((V+E)logV)β”‚ O(V)        β”‚ μ΅œμ†Œ νž™ μ‚¬μš©        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

V = 정점 수, E = κ°„μ„  수

λ‹€μŒ 단계


참고 자료

to navigate between lessons