Home [BOJ] μœ„μƒ μ •λ ¬ πŸ₯‡3
Post
Cancel

[BOJ] μœ„μƒ μ •λ ¬ πŸ₯‡3

πŸ“š Topological Sort

좜처 : https://www.acmicpc.net/problem/9470


πŸ’‘ 풀이

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import sys
from collections import deque

input = sys.stdin.readline

T = int(input())
for _ in range(T):
    k, m, p = map(int, input().split())                 # ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ 번호, λ…Έλ“œ 개수, κ°„μ„  수

    graph = [[] for _ in range(m + 1)]
    inDegree = [0] * (m + 1)                            # μ§„μž…μ°¨μˆ˜
    dp = [[0] * (m + 1) for _ in range(m + 1)]
    end = 0                                             # λ§ˆμ§€λ§‰ λ…Έλ“œ 번호

    for _ in range(p):                                  # κ·Έλž˜ν”„μ™€ μ§„μž… 차수 μ„€μ •
        a, b = map(int, input().split())
        graph[a].append(b)
        inDegree[b] += 1

    queue = deque()
    for i in range(1, m + 1):                           # μ§„μž… μ°¨μˆ˜κ°€ 0인 λ…Έλ“œλ₯Ό queue에 μΆ”κ°€
        if inDegree[i] == 0:
            queue.append(i)
            dp[i][i] = 1

    while queue:
        x = queue.popleft()
        end = x

        for i in graph[x]:
            inDegree[i] -= 1

            dp[x][i] = dp[x][x]

            if inDegree[i] == 0:
                queue.append(i)
                
                max_ = 0
                count = 0
                for row in range(1, m + 1):
                    if max_ != 0 and dp[row][i] == max_:    # κ°€μž₯ 큰 κ°•μ˜ 개수 μΉ΄μš΄νŒ…
                        count += 1
                    elif dp[row][i] > max_:                 # κ°€μž₯ 큰 κ°•μ˜ 개수 μ°ΎκΈ°
                        max_ = dp[row][i]
                        count = 1

                dp[i][i] = max_ if count == 1 else max_ + 1

    print(k, dp[end][end])
print(*result)


πŸ“ ν•΄μ„€

1. μ•„λž˜μ™€ 같은 2차원 리슀트(μ΄ν•˜ dp)κ°€ μžˆλ‹€κ³  κ°€μ •ν•œλ‹€.

image

2. μ§„μž… μ°¨μˆ˜κ°€ 0인 λ…Έλ“œμ˜ 번호λ₯Ό i라고 κ°€μ •ν•˜λ©΄, dp[i][i]에 1둜 μ„€μ •ν•œλ‹€.

image

3. λ…Έλ“œ aμ—μ„œ λ…Έλ“œ b둜 κ°€λŠ” κ²½λ‘œκ°€ μžˆλ‹€λ©΄, μ§„μž… 차수λ₯Ό κ°μ†Œμ‹œν‚€κ³  dp[a][b]의 값을 dp[a][a] κ°’μœΌλ‘œ λ³€ν™˜ν•œλ‹€.

image

4. μ§„μž… μ°¨μˆ˜κ°€ 0이 λ˜μ—ˆλ‹€λ©΄, queue에 λ…Έλ“œ 번호λ₯Ό λ„£κ³ , μ•„λž˜μ˜ 쑰건에 따라 dp ν…Œμ΄λΈ”μ˜ 값을 κ°±μ‹ ν•œλ‹€.

  • λ…Έλ“œ 번호 vμ—μ„œ ν•΄λ‹Ή λ…Έλ“œλ‘œ λ“€μ–΄μ˜€λŠ” κ°•μ˜ μˆœμ„œ 쀑 κ°€μž₯ 큰 값을 i라고 ν•˜μ˜€μ„ λ•Œ
  • ν•΄λ‹Ή λ…Έλ“œλ‘œ λ“€μ–΄μ˜€λŠ” λͺ¨λ“  κ°• μ€‘μ—μ„œ κ°•μ˜ μˆœμ„œκ°€ i인 강이 1개이면, dp[v][v]의 값을 i둜 μ„€μ •ν•œλ‹€.
  • i인 강이 2개 이상이면 dp[v][v]의 값을 i + 1둜 μ„€μ •ν•œλ‹€.

image

5. κ³Όμ • 3 ~ 4λ₯Ό λ°˜λ³΅ν•˜λ©΄ μ•„λž˜μ™€ 같은 dp ν…Œμ΄λΈ”μ΄ λ§Œλ“€μ–΄μ§„λ‹€.

image

6. λ§ˆμ§€λ§‰ λ…Έλ“œλ₯Ό v라고 ν•œλ‹€λ©΄, ν•˜μ²œκ³„μ˜ Strahler μˆœμ„œλŠ” dp[v][v]κ°€ λœλ‹€.

image


πŸ’£ κ³ λ €ν•˜μ§€ μ•Šμ•„λ„ λ˜λŠ” 사항

dp[x][i] = dp[x][x]

  • queue.popleft()λ₯Ό 톡해 λ‚˜μ˜¨ λ…Έλ“œ λ²ˆν˜Έκ°€ v라고 ν–ˆμ„ λ•Œ, dp[v][v] 값은 항상 μ‘΄μž¬ν•œλ‹€.

dp[i][i] = max_ if count == 1 else max_ + 1

  • μ‹œμž‘ 지점이 μ•„λ‹Œ λͺ¨λ“  λ…Έλ“œμ—λŠ” μ§„μž… 간선이 μ‘΄μž¬ν•˜λ―€λ‘œ λ³€μˆ˜ max_λŠ” μ΅œμ†Œ 1의 값을 κ°€μ§€κ²Œ λœλ‹€.
  • dp[i][i]λŠ” μ‹œμž‘ 지점이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ—, κ°€μž₯ 큰 κ°•μ˜ 개수 iκ°€ 1κ°œμΈμ§€, 2개 μ΄μƒμΈμ§€λ§Œμ„ κ³ λ €ν•˜λ©΄ λœλ‹€.


This post is licensed under CC BY 4.0 by the author.

[BOJ] μœ„μƒ μ •λ ¬ Basic

Async-Nonblocking