SlideShare a Scribd company logo
서울시립대 알고리즘 소모임
위상 정렬
2020년 여름 방학 5주차
강의자 소개
2020 AL林 정기 스터디 2
이름 최문기
소속 서울시립대 컴퓨터과학부(16학번)
핸들 iknoom1107(BOJ) IKnoom(Codeforces) IKnoom(AtCoder)
ICPC 팀 Iknoom Cannot Participate Contest(ICPC)
- 김정현, 최문기, 최연웅
2020 AL林 정기 스터디 3
위상 정렬
위상 정렬(Topological Sorting)
2020 AL林 정기 스터디 4
의존성이 있는 작업들이 주어질 때, 수행해야 하는 순서
유향 그래프의 정점을 방향을 거스르지 않도록 나열하는 것
(유향 그래프의 정점을 정렬하는 것)
“간선 (i, j)가 존재하면 정렬 결과에서 정점 i는 반드시 정점 j보다 앞에 위치해야 한다.”
위상 정렬(Topological Sorting)
2020 AL林 정기 스터디 5
“간선 (i, j)가 존재하면 정렬 결과에서 정점 i는 반드시 정점 j보다 앞에 위치해야 한다.”
정렬할 그래프는
1. 유향 그래프이며
2. 사이클이 없어야 합니다. (위 성질을 만족할 수 없죠)
※ 참고
2020 AL林 정기 스터디 6
이러한 그래프를
DAG(Directed Acyclic Graph)라고 합니다.
※ 의존성 그래프(dependency graph)라고 하기도 합니다
정렬할 그래프는
1. 유향 그래프이며
2. 사이클이 없어야 합니다.
위상 정렬의 예
2020 AL林 정기 스터디 7
1. 대학의 선수과목
2. 요리
3. 스타크래프트
등등...
위상 정렬의 예
2020 AL林 정기 스터디 8
위상 정렬의 예
2020 AL林 정기 스터디 9
점화
냄비에
물 넣기
라면
뜯기
라면
넣기
스프
넣기
계란
넣기
위상 정렬의 예
2020 AL林 정기 스터디 10
풀어볼 문제 줄 세우기(BOJ 2252번)
2020 AL林 정기 스터디 11
https://www.acmicpc.net/problem/2252
N명의 학생들을 키 순서대로 줄을 세우려고 한다.
각 학생의 키를 직접 재서 정렬하면 간단하겠지만, 마땅한 방법이 없어서 두 학생의 키를 비교하는 방법을 사용하
기로 하였다. 그나마도 모든 학생들을 다 비교해 본 것이 아니고, 일부 학생들의 키만을 비교해 보았다.
일부 학생들의 키를 비교한 결과가 주어졌을 때, 줄을 세우는 프로그램을 작성하시오.
풀어볼 문제 줄 세우기(BOJ 2252번)
2020 AL林 정기 스터디 12
[입력]
N = 3
M = 2
1 < 3
2 < 3
학생들의 번호는 1번부터 N번, M은 키를 비교한 회수
답이 여러 가지인 경우에는 아무거나 출력한다.
[출력]
1 2 3
풀어볼 문제 줄 세우기(BOJ 2252번)
2020 AL林 정기 스터디 13
[입력]
N = 8, M = 6
1 4
2 3
2 4
4 5
6 7
5 8
[출력]
1 2 3 4 6 5 7 8
2020 AL林 정기 스터디 14
위상 정렬 알고리즘
위상 정렬 알고리즘
2020 AL林 정기 스터디 15
알고리즘 1 Queue를 이용한 기본적인 방법 (BFS)
알고리즘 2 DFS를 이용한 방법
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 16
“진입 간선이 없는 정점을 선택하고 제거한다”
진입 간선 진출 간선
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 17
더 구체적으로
for i ← 1 to n {
① 진입 간선이 없는 정점 u를 선택한다.
② A[i] = u
③ 정점 u와 u의 진출 간선을 모두 제거한다.
}
return A[]
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 18
Answer
[ ]
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 19
Answer
[ 1 ]
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 20
Answer
[ 1 2 ]
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 21
Answer
[ 1 2 3 4 6 ]
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 22
Answer
[ 1 2 3 4 6 5 7 ]
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 23
Answer
[ 1 2 3 4 6 5 7 8 ]
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 24
아이디어는 쉽습니다.
하지만 어떻게 구현해야 효율적일까요?
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 25
for i ← 1 to n {
① 진입 간선이 없는 정점 u를 선택한다.
② A[i] = u
③ 정점 u와 u의 진출 간선을 모두 제거한다.
}
return A[]
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 26
Q = Queue()
INDEGREE = [0, 0, ..., 0]
1. 각 정점마다 진입 간선의 수를 INDEGREE에 저장한다.
2. 진입 간선이 없는 정점(INDEGREE[i] == 0)을 모두 Q에 넣는다.
위상 정렬 알고리즘 ① : Queue
2020 AL林 정기 스터디 27
result = List()
while (Q is not empty) {
① u = Q.pop()
② result.push(u)
③ for (u에 인접한 정점 v에 대해서){
INDEGREE[v] -= 1
if (INDEGREE[v] == 0) Q.push(v)
}
}
return result
위상 정렬 알고리즘 ① : 소스코드(python)
2020 AL林 정기 스터디 28
위상 정렬 알고리즘 ① : 소스코드(python)
2020 AL林 정기 스터디 29
위상 정렬 알고리즘 ① : 소스코드(python)
2020 AL林 정기 스터디 30
Queue 풀이 (소스코드 전체)
http://boj.kr/e6f76e4167714f60852b3cf559aaefad
위상 정렬 알고리즘 ② : DFS
2020 AL林 정기 스터디 31
사실 방금까지 한 위상 정렬은
DFS 종료 순서를 뒤집기만 하면 됩니다.
위상 정렬 알고리즘 ② : DFS
2020 AL林 정기 스터디 32
DFS(u) {
visited[u] = True
for (u에 인접한 정점 v에 대해서)
if (visited[v] = False) DFS(v)
result.push(u)
}
위상 정렬 알고리즘 ② : DFS
2020 AL林 정기 스터디 33
result = List()
for (모든 정점 u에 대해서)
visited[u] = False
for (모든 정점 u에 대해서)
if (visited[u] = False) DFS(u)
reverse(result) // result 를 뒤집는다.
return result
위상 정렬 알고리즘 ② : 소스코드(python)
2020 AL林 정기 스터디 34
위상 정렬 알고리즘 ② : 소스코드(python)
2020 AL林 정기 스터디 35
위상 정렬 알고리즘 ② : 소스코드(python)
2020 AL林 정기 스터디 36
DFS 풀이 (소스코드 전체)
http://boj.kr/1db6303b1a6a47c48abc2723cf2b7cd9
위상 정렬 알고리즘 ② : DFS
2020 AL林 정기 스터디 37
이 방법은 먼저 알아본 방법에 비해서
상당히 비직관적입니다.
이 알고리즘의 정당성을 증명해볼까요?
위상 정렬 알고리즘 ② : DFS 정당성
2020 AL林 정기 스터디 38
귀류법으로 증명합니다. (알고리즘 문제 해결 전략 831페이지를 참고했습니다.)
위상 정렬 결과에서 역행하는 간선 (u,v)가 있다고 가정해봅시다.
위상 정렬 결과의 예 : {3, 2, ... , v, ... ,u, ..., 9, ...}
이 결과가 나오기 위해서는 dfs(u)가 종료한 후 dfs(v)가 종료했다는 것입니다.
dfs(u)는 종료 전에 인접한 간선을 모두 보기 때문에 (u,v) 또한 검사했을 것입니다.
위상 정렬 알고리즘 ② : DFS 정당성
2020 AL林 정기 스터디 39
이때 dfs(u)에서
1. visited[v]가 거짓일 경우
dfs(u)를 dfs(v)를 재귀 호출했을 것입니다.
따라서 dfs(v)가 종료된 후에 dfs(u)가 종료되었을 것이고 v는 u의 왼쪽에 있을 수 없습니다.
2. visited[v]가 참일 경우
dfs(v)는 이미 한번 호출되었어야 합니다.
그런데 dfs(v)가 dfs(u)보다 늦게 끝나기 위해서는, dfs(v)가 현재 실행 중이어야 합니다.
이렇게 되기 위해서는 v에서 u로 가는 경로가 필요합니다. (dfs(v) -> dfs(u)로 재귀호출)
하지만 그렇다면 그래프는 사이클을 형성합니다.
위상 정렬 알고리즘 ② : DFS
2020 AL林 정기 스터디 40
따라서 DFS로 얻어낸 위상 정렬의 결과에서
(u, v)인 간선이 있을 경우
u는 v의 왼쪽에 있을 수 밖에 없습니다!
2020 AL林 정기 스터디 41
그 외 잡다한 이야기들..
다시보기
2020 AL林 정기 스터디 42
result = List()
while (Q is not empty) {
① u = Q.pop()
② result.push(u)
③ for (u에 인접한 정점 v에 대해서){
INDEGREE[v] -= 1
if (INDEGREE[v] == 0) Q.push(v)
}
}
return result
큐의 크기를 통해서 알 수 있는 것
2020 AL林 정기 스터디 43
① 중간에 큐가 비어버리면 (루프가 N번 진행되지 않으면)
위상 정렬이 불가능한데 이 경우는 사이클이 있는 경우입니다.
(사이클이 있으면 위상정렬을 할 수 없다고 했죠.)
② 중간에 큐의 크기가 2 이상인 경우가 있다면
위상 정렬의 결과가 2개 이상입니다.
(큐에서 pop할 때 빼낼 수 있는 원소가 여러개라서 그렇습니다.)
Queue(BFS) vs DFS
2020 AL林 정기 스터디 44
일단 Queue를 이용한 방법이 더 직관적이고
딱히 DFS를 이용하지 않아도 위상 정렬 문제들은 풀립니다.
(저는 위상정렬 문제 대부분 Queue 써서 풀었습니다.)
하지만 알고리즘 대회를 준비한다면
DFS를 이용한 위상 정렬도 알아두는게 좋습니다.
(2-SAT에서 SCC DAG 위상 정렬할 때 써요)
earliest time
2020 AL林 정기 스터디 45
DP + Topological Sort
연습문제 : 작업 (BOJ 2056 ), ACM Craft (BOJ 1005)
https://www.acmicpc.net/problem/2056
https://www.acmicpc.net/problem/1005
critical path(임계경로)
2020 AL林 정기 스터디 46
A critical path is a longest path through the DAG, corresponding to the
longest time to perform any sequence of jobs. Thus, the weight of a critical
path provides a lower bound on the total time to perform all the jobs.
연습문제 : 임계경로 (BOJ 1948)
https://www.acmicpc.net/problem/1948
What’s New In Python 3.9
2020 AL林 정기 스터디 47
연습 문제
2020 AL林 정기 스터디
48
위상 정렬
2252 줄 세우기
2623 음악프로그램
1766 문제집
3665 최종 순위
2056 작업
1005 ACM Craft

More Related Content

What's hot

확통 회귀분석
확통 회귀분석확통 회귀분석
확통 회귀분석
jaypi Ko
 
딥러닝기본-신경망기초
딥러닝기본-신경망기초딥러닝기본-신경망기초
딥러닝기본-신경망기초
jaypi Ko
 
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
NAVER D2
 
HI-ARC Number Theory
HI-ARC Number TheoryHI-ARC Number Theory
HI-ARC Number Theory
Jae-yeol Lee
 
Dynamic Programming : Step by Step
Dynamic Programming : Step by StepDynamic Programming : Step by Step
Dynamic Programming : Step by Step
인서 박
 
이산수학[1].110707.l01.행렬
이산수학[1].110707.l01.행렬이산수학[1].110707.l01.행렬
이산수학[1].110707.l01.행렬Jung-Ho Kim
 
[신경망기초] 신경망의시작-퍼셉트론
[신경망기초] 신경망의시작-퍼셉트론[신경망기초] 신경망의시작-퍼셉트론
[신경망기초] 신경망의시작-퍼셉트론
jaypi Ko
 
[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part
[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part
[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part
NAVER D2
 
Backtracking [ICPC Sinchon]
Backtracking [ICPC Sinchon]Backtracking [ICPC Sinchon]
Backtracking [ICPC Sinchon]
Jae-yeol Lee
 
머신 러닝을 해보자 3장 (2022년 스터디)
머신 러닝을 해보자 3장 (2022년 스터디)머신 러닝을 해보자 3장 (2022년 스터디)
머신 러닝을 해보자 3장 (2022년 스터디)
ssusercdf17c
 
Tree algorithm
Tree algorithmTree algorithm
Tree algorithm
승혁 조
 
2019 고려대학교 프로그래밍 경시대회 풀이
2019 고려대학교 프로그래밍 경시대회 풀이2019 고려대학교 프로그래밍 경시대회 풀이
2019 고려대학교 프로그래밍 경시대회 풀이
Subin An
 
알고리즘
알고리즘알고리즘
알고리즘
Kwang-Hyun Park
 
[연세대 모르고리즘] 프로그래밍 경진대회 문제 풀이
[연세대 모르고리즘] 프로그래밍 경진대회 문제 풀이[연세대 모르고리즘] 프로그래밍 경진대회 문제 풀이
[연세대 모르고리즘] 프로그래밍 경진대회 문제 풀이
NAVER D2
 
머신 러닝을 해보자 1장 (2022년 스터디)
머신 러닝을 해보자 1장 (2022년 스터디)머신 러닝을 해보자 1장 (2022년 스터디)
머신 러닝을 해보자 1장 (2022년 스터디)
ssusercdf17c
 
Tree LIS (2015.03.29)
Tree LIS (2015.03.29)Tree LIS (2015.03.29)
Tree LIS (2015.03.29)
Jaehyun Koo
 
2009 PPT 발표 대회 - P.S.R.
2009 PPT 발표 대회 - P.S.R.2009 PPT 발표 대회 - P.S.R.
2009 PPT 발표 대회 - P.S.R.Kyunghoon Kim
 
Introduce shortest path algorithms(Korean)
Introduce shortest path algorithms(Korean)Introduce shortest path algorithms(Korean)
Introduce shortest path algorithms(Korean)
Wonjae Kim
 
IOI 2005 정원 분할 (2015.03.05)
IOI 2005 정원 분할 (2015.03.05)IOI 2005 정원 분할 (2015.03.05)
IOI 2005 정원 분할 (2015.03.05)
Jaehyun Koo
 
The Art of Computer Programming 2.3.2 Tree
The Art of Computer Programming 2.3.2 TreeThe Art of Computer Programming 2.3.2 Tree
The Art of Computer Programming 2.3.2 Tree
hyun soomyung
 

What's hot (20)

확통 회귀분석
확통 회귀분석확통 회귀분석
확통 회귀분석
 
딥러닝기본-신경망기초
딥러닝기본-신경망기초딥러닝기본-신경망기초
딥러닝기본-신경망기초
 
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
 
HI-ARC Number Theory
HI-ARC Number TheoryHI-ARC Number Theory
HI-ARC Number Theory
 
Dynamic Programming : Step by Step
Dynamic Programming : Step by StepDynamic Programming : Step by Step
Dynamic Programming : Step by Step
 
이산수학[1].110707.l01.행렬
이산수학[1].110707.l01.행렬이산수학[1].110707.l01.행렬
이산수학[1].110707.l01.행렬
 
[신경망기초] 신경망의시작-퍼셉트론
[신경망기초] 신경망의시작-퍼셉트론[신경망기초] 신경망의시작-퍼셉트론
[신경망기초] 신경망의시작-퍼셉트론
 
[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part
[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part
[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part
 
Backtracking [ICPC Sinchon]
Backtracking [ICPC Sinchon]Backtracking [ICPC Sinchon]
Backtracking [ICPC Sinchon]
 
머신 러닝을 해보자 3장 (2022년 스터디)
머신 러닝을 해보자 3장 (2022년 스터디)머신 러닝을 해보자 3장 (2022년 스터디)
머신 러닝을 해보자 3장 (2022년 스터디)
 
Tree algorithm
Tree algorithmTree algorithm
Tree algorithm
 
2019 고려대학교 프로그래밍 경시대회 풀이
2019 고려대학교 프로그래밍 경시대회 풀이2019 고려대학교 프로그래밍 경시대회 풀이
2019 고려대학교 프로그래밍 경시대회 풀이
 
알고리즘
알고리즘알고리즘
알고리즘
 
[연세대 모르고리즘] 프로그래밍 경진대회 문제 풀이
[연세대 모르고리즘] 프로그래밍 경진대회 문제 풀이[연세대 모르고리즘] 프로그래밍 경진대회 문제 풀이
[연세대 모르고리즘] 프로그래밍 경진대회 문제 풀이
 
머신 러닝을 해보자 1장 (2022년 스터디)
머신 러닝을 해보자 1장 (2022년 스터디)머신 러닝을 해보자 1장 (2022년 스터디)
머신 러닝을 해보자 1장 (2022년 스터디)
 
Tree LIS (2015.03.29)
Tree LIS (2015.03.29)Tree LIS (2015.03.29)
Tree LIS (2015.03.29)
 
2009 PPT 발표 대회 - P.S.R.
2009 PPT 발표 대회 - P.S.R.2009 PPT 발표 대회 - P.S.R.
2009 PPT 발표 대회 - P.S.R.
 
Introduce shortest path algorithms(Korean)
Introduce shortest path algorithms(Korean)Introduce shortest path algorithms(Korean)
Introduce shortest path algorithms(Korean)
 
IOI 2005 정원 분할 (2015.03.05)
IOI 2005 정원 분할 (2015.03.05)IOI 2005 정원 분할 (2015.03.05)
IOI 2005 정원 분할 (2015.03.05)
 
The Art of Computer Programming 2.3.2 Tree
The Art of Computer Programming 2.3.2 TreeThe Art of Computer Programming 2.3.2 Tree
The Art of Computer Programming 2.3.2 Tree
 

More from Moonki Choi

2021 여름방학 정기 세미나 3주차
2021 여름방학 정기 세미나 3주차2021 여름방학 정기 세미나 3주차
2021 여름방학 정기 세미나 3주차
Moonki Choi
 
2021 여름방학 정기 세미나 1주차
2021 여름방학 정기 세미나 1주차2021 여름방학 정기 세미나 1주차
2021 여름방학 정기 세미나 1주차
Moonki Choi
 
2021 알림 오세요
2021 알림 오세요2021 알림 오세요
2021 알림 오세요
Moonki Choi
 
2021 1학기 정기 세미나 3주차
2021 1학기 정기 세미나 3주차2021 1학기 정기 세미나 3주차
2021 1학기 정기 세미나 3주차
Moonki Choi
 
2021 1학기 정기 세미나 2주차
2021 1학기 정기 세미나 2주차2021 1학기 정기 세미나 2주차
2021 1학기 정기 세미나 2주차
Moonki Choi
 
2020 겨울방학 정기스터디 3주차
2020 겨울방학 정기스터디 3주차2020 겨울방학 정기스터디 3주차
2020 겨울방학 정기스터디 3주차
Moonki Choi
 
2020 겨울방학 정기스터디 2주차
2020 겨울방학 정기스터디 2주차2020 겨울방학 정기스터디 2주차
2020 겨울방학 정기스터디 2주차
Moonki Choi
 
2020 2학기 정기스터디 8주차
2020 2학기 정기스터디 8주차2020 2학기 정기스터디 8주차
2020 2학기 정기스터디 8주차
Moonki Choi
 
2020 2학기 정기스터디 1주차
2020 2학기 정기스터디 1주차2020 2학기 정기스터디 1주차
2020 2학기 정기스터디 1주차
Moonki Choi
 
2020 1학기 정기스터디 2주차
2020 1학기 정기스터디 2주차2020 1학기 정기스터디 2주차
2020 1학기 정기스터디 2주차
Moonki Choi
 
2020 1학기 정기스터디 1주차
2020 1학기 정기스터디 1주차2020 1학기 정기스터디 1주차
2020 1학기 정기스터디 1주차
Moonki Choi
 

More from Moonki Choi (11)

2021 여름방학 정기 세미나 3주차
2021 여름방학 정기 세미나 3주차2021 여름방학 정기 세미나 3주차
2021 여름방학 정기 세미나 3주차
 
2021 여름방학 정기 세미나 1주차
2021 여름방학 정기 세미나 1주차2021 여름방학 정기 세미나 1주차
2021 여름방학 정기 세미나 1주차
 
2021 알림 오세요
2021 알림 오세요2021 알림 오세요
2021 알림 오세요
 
2021 1학기 정기 세미나 3주차
2021 1학기 정기 세미나 3주차2021 1학기 정기 세미나 3주차
2021 1학기 정기 세미나 3주차
 
2021 1학기 정기 세미나 2주차
2021 1학기 정기 세미나 2주차2021 1학기 정기 세미나 2주차
2021 1학기 정기 세미나 2주차
 
2020 겨울방학 정기스터디 3주차
2020 겨울방학 정기스터디 3주차2020 겨울방학 정기스터디 3주차
2020 겨울방학 정기스터디 3주차
 
2020 겨울방학 정기스터디 2주차
2020 겨울방학 정기스터디 2주차2020 겨울방학 정기스터디 2주차
2020 겨울방학 정기스터디 2주차
 
2020 2학기 정기스터디 8주차
2020 2학기 정기스터디 8주차2020 2학기 정기스터디 8주차
2020 2학기 정기스터디 8주차
 
2020 2학기 정기스터디 1주차
2020 2학기 정기스터디 1주차2020 2학기 정기스터디 1주차
2020 2학기 정기스터디 1주차
 
2020 1학기 정기스터디 2주차
2020 1학기 정기스터디 2주차2020 1학기 정기스터디 2주차
2020 1학기 정기스터디 2주차
 
2020 1학기 정기스터디 1주차
2020 1학기 정기스터디 1주차2020 1학기 정기스터디 1주차
2020 1학기 정기스터디 1주차
 

2020 여름방학 정기스터디 5주차

  • 1. 서울시립대 알고리즘 소모임 위상 정렬 2020년 여름 방학 5주차
  • 2. 강의자 소개 2020 AL林 정기 스터디 2 이름 최문기 소속 서울시립대 컴퓨터과학부(16학번) 핸들 iknoom1107(BOJ) IKnoom(Codeforces) IKnoom(AtCoder) ICPC 팀 Iknoom Cannot Participate Contest(ICPC) - 김정현, 최문기, 최연웅
  • 3. 2020 AL林 정기 스터디 3 위상 정렬
  • 4. 위상 정렬(Topological Sorting) 2020 AL林 정기 스터디 4 의존성이 있는 작업들이 주어질 때, 수행해야 하는 순서 유향 그래프의 정점을 방향을 거스르지 않도록 나열하는 것 (유향 그래프의 정점을 정렬하는 것) “간선 (i, j)가 존재하면 정렬 결과에서 정점 i는 반드시 정점 j보다 앞에 위치해야 한다.”
  • 5. 위상 정렬(Topological Sorting) 2020 AL林 정기 스터디 5 “간선 (i, j)가 존재하면 정렬 결과에서 정점 i는 반드시 정점 j보다 앞에 위치해야 한다.” 정렬할 그래프는 1. 유향 그래프이며 2. 사이클이 없어야 합니다. (위 성질을 만족할 수 없죠)
  • 6. ※ 참고 2020 AL林 정기 스터디 6 이러한 그래프를 DAG(Directed Acyclic Graph)라고 합니다. ※ 의존성 그래프(dependency graph)라고 하기도 합니다 정렬할 그래프는 1. 유향 그래프이며 2. 사이클이 없어야 합니다.
  • 7. 위상 정렬의 예 2020 AL林 정기 스터디 7 1. 대학의 선수과목 2. 요리 3. 스타크래프트 등등...
  • 8. 위상 정렬의 예 2020 AL林 정기 스터디 8
  • 9. 위상 정렬의 예 2020 AL林 정기 스터디 9 점화 냄비에 물 넣기 라면 뜯기 라면 넣기 스프 넣기 계란 넣기
  • 10. 위상 정렬의 예 2020 AL林 정기 스터디 10
  • 11. 풀어볼 문제 줄 세우기(BOJ 2252번) 2020 AL林 정기 스터디 11 https://www.acmicpc.net/problem/2252 N명의 학생들을 키 순서대로 줄을 세우려고 한다. 각 학생의 키를 직접 재서 정렬하면 간단하겠지만, 마땅한 방법이 없어서 두 학생의 키를 비교하는 방법을 사용하 기로 하였다. 그나마도 모든 학생들을 다 비교해 본 것이 아니고, 일부 학생들의 키만을 비교해 보았다. 일부 학생들의 키를 비교한 결과가 주어졌을 때, 줄을 세우는 프로그램을 작성하시오.
  • 12. 풀어볼 문제 줄 세우기(BOJ 2252번) 2020 AL林 정기 스터디 12 [입력] N = 3 M = 2 1 < 3 2 < 3 학생들의 번호는 1번부터 N번, M은 키를 비교한 회수 답이 여러 가지인 경우에는 아무거나 출력한다. [출력] 1 2 3
  • 13. 풀어볼 문제 줄 세우기(BOJ 2252번) 2020 AL林 정기 스터디 13 [입력] N = 8, M = 6 1 4 2 3 2 4 4 5 6 7 5 8 [출력] 1 2 3 4 6 5 7 8
  • 14. 2020 AL林 정기 스터디 14 위상 정렬 알고리즘
  • 15. 위상 정렬 알고리즘 2020 AL林 정기 스터디 15 알고리즘 1 Queue를 이용한 기본적인 방법 (BFS) 알고리즘 2 DFS를 이용한 방법
  • 16. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 16 “진입 간선이 없는 정점을 선택하고 제거한다” 진입 간선 진출 간선
  • 17. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 17 더 구체적으로 for i ← 1 to n { ① 진입 간선이 없는 정점 u를 선택한다. ② A[i] = u ③ 정점 u와 u의 진출 간선을 모두 제거한다. } return A[]
  • 18. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 18 Answer [ ]
  • 19. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 19 Answer [ 1 ]
  • 20. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 20 Answer [ 1 2 ]
  • 21. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 21 Answer [ 1 2 3 4 6 ]
  • 22. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 22 Answer [ 1 2 3 4 6 5 7 ]
  • 23. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 23 Answer [ 1 2 3 4 6 5 7 8 ]
  • 24. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 24 아이디어는 쉽습니다. 하지만 어떻게 구현해야 효율적일까요?
  • 25. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 25 for i ← 1 to n { ① 진입 간선이 없는 정점 u를 선택한다. ② A[i] = u ③ 정점 u와 u의 진출 간선을 모두 제거한다. } return A[]
  • 26. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 26 Q = Queue() INDEGREE = [0, 0, ..., 0] 1. 각 정점마다 진입 간선의 수를 INDEGREE에 저장한다. 2. 진입 간선이 없는 정점(INDEGREE[i] == 0)을 모두 Q에 넣는다.
  • 27. 위상 정렬 알고리즘 ① : Queue 2020 AL林 정기 스터디 27 result = List() while (Q is not empty) { ① u = Q.pop() ② result.push(u) ③ for (u에 인접한 정점 v에 대해서){ INDEGREE[v] -= 1 if (INDEGREE[v] == 0) Q.push(v) } } return result
  • 28. 위상 정렬 알고리즘 ① : 소스코드(python) 2020 AL林 정기 스터디 28
  • 29. 위상 정렬 알고리즘 ① : 소스코드(python) 2020 AL林 정기 스터디 29
  • 30. 위상 정렬 알고리즘 ① : 소스코드(python) 2020 AL林 정기 스터디 30 Queue 풀이 (소스코드 전체) http://boj.kr/e6f76e4167714f60852b3cf559aaefad
  • 31. 위상 정렬 알고리즘 ② : DFS 2020 AL林 정기 스터디 31 사실 방금까지 한 위상 정렬은 DFS 종료 순서를 뒤집기만 하면 됩니다.
  • 32. 위상 정렬 알고리즘 ② : DFS 2020 AL林 정기 스터디 32 DFS(u) { visited[u] = True for (u에 인접한 정점 v에 대해서) if (visited[v] = False) DFS(v) result.push(u) }
  • 33. 위상 정렬 알고리즘 ② : DFS 2020 AL林 정기 스터디 33 result = List() for (모든 정점 u에 대해서) visited[u] = False for (모든 정점 u에 대해서) if (visited[u] = False) DFS(u) reverse(result) // result 를 뒤집는다. return result
  • 34. 위상 정렬 알고리즘 ② : 소스코드(python) 2020 AL林 정기 스터디 34
  • 35. 위상 정렬 알고리즘 ② : 소스코드(python) 2020 AL林 정기 스터디 35
  • 36. 위상 정렬 알고리즘 ② : 소스코드(python) 2020 AL林 정기 스터디 36 DFS 풀이 (소스코드 전체) http://boj.kr/1db6303b1a6a47c48abc2723cf2b7cd9
  • 37. 위상 정렬 알고리즘 ② : DFS 2020 AL林 정기 스터디 37 이 방법은 먼저 알아본 방법에 비해서 상당히 비직관적입니다. 이 알고리즘의 정당성을 증명해볼까요?
  • 38. 위상 정렬 알고리즘 ② : DFS 정당성 2020 AL林 정기 스터디 38 귀류법으로 증명합니다. (알고리즘 문제 해결 전략 831페이지를 참고했습니다.) 위상 정렬 결과에서 역행하는 간선 (u,v)가 있다고 가정해봅시다. 위상 정렬 결과의 예 : {3, 2, ... , v, ... ,u, ..., 9, ...} 이 결과가 나오기 위해서는 dfs(u)가 종료한 후 dfs(v)가 종료했다는 것입니다. dfs(u)는 종료 전에 인접한 간선을 모두 보기 때문에 (u,v) 또한 검사했을 것입니다.
  • 39. 위상 정렬 알고리즘 ② : DFS 정당성 2020 AL林 정기 스터디 39 이때 dfs(u)에서 1. visited[v]가 거짓일 경우 dfs(u)를 dfs(v)를 재귀 호출했을 것입니다. 따라서 dfs(v)가 종료된 후에 dfs(u)가 종료되었을 것이고 v는 u의 왼쪽에 있을 수 없습니다. 2. visited[v]가 참일 경우 dfs(v)는 이미 한번 호출되었어야 합니다. 그런데 dfs(v)가 dfs(u)보다 늦게 끝나기 위해서는, dfs(v)가 현재 실행 중이어야 합니다. 이렇게 되기 위해서는 v에서 u로 가는 경로가 필요합니다. (dfs(v) -> dfs(u)로 재귀호출) 하지만 그렇다면 그래프는 사이클을 형성합니다.
  • 40. 위상 정렬 알고리즘 ② : DFS 2020 AL林 정기 스터디 40 따라서 DFS로 얻어낸 위상 정렬의 결과에서 (u, v)인 간선이 있을 경우 u는 v의 왼쪽에 있을 수 밖에 없습니다!
  • 41. 2020 AL林 정기 스터디 41 그 외 잡다한 이야기들..
  • 42. 다시보기 2020 AL林 정기 스터디 42 result = List() while (Q is not empty) { ① u = Q.pop() ② result.push(u) ③ for (u에 인접한 정점 v에 대해서){ INDEGREE[v] -= 1 if (INDEGREE[v] == 0) Q.push(v) } } return result
  • 43. 큐의 크기를 통해서 알 수 있는 것 2020 AL林 정기 스터디 43 ① 중간에 큐가 비어버리면 (루프가 N번 진행되지 않으면) 위상 정렬이 불가능한데 이 경우는 사이클이 있는 경우입니다. (사이클이 있으면 위상정렬을 할 수 없다고 했죠.) ② 중간에 큐의 크기가 2 이상인 경우가 있다면 위상 정렬의 결과가 2개 이상입니다. (큐에서 pop할 때 빼낼 수 있는 원소가 여러개라서 그렇습니다.)
  • 44. Queue(BFS) vs DFS 2020 AL林 정기 스터디 44 일단 Queue를 이용한 방법이 더 직관적이고 딱히 DFS를 이용하지 않아도 위상 정렬 문제들은 풀립니다. (저는 위상정렬 문제 대부분 Queue 써서 풀었습니다.) 하지만 알고리즘 대회를 준비한다면 DFS를 이용한 위상 정렬도 알아두는게 좋습니다. (2-SAT에서 SCC DAG 위상 정렬할 때 써요)
  • 45. earliest time 2020 AL林 정기 스터디 45 DP + Topological Sort 연습문제 : 작업 (BOJ 2056 ), ACM Craft (BOJ 1005) https://www.acmicpc.net/problem/2056 https://www.acmicpc.net/problem/1005
  • 46. critical path(임계경로) 2020 AL林 정기 스터디 46 A critical path is a longest path through the DAG, corresponding to the longest time to perform any sequence of jobs. Thus, the weight of a critical path provides a lower bound on the total time to perform all the jobs. 연습문제 : 임계경로 (BOJ 1948) https://www.acmicpc.net/problem/1948
  • 47. What’s New In Python 3.9 2020 AL林 정기 스터디 47
  • 48. 연습 문제 2020 AL林 정기 스터디 48 위상 정렬 2252 줄 세우기 2623 음악프로그램 1766 문제집 3665 최종 순위 2056 작업 1005 ACM Craft